How to received promises from backend in Firebase httpscallable().call()?












1















I've been playing around with stripe and would like to learn how to get ephemeral keys in the following way:



Back-end:



//Stripe API requirement for payment
exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
const uid = context.auth.uid;

//Get values
admin.database().ref().child("users").child(uid)
.on("value", (snapshot) =>{
//Get user data
let user = snapshot.val()

//Log data
console.log("Create ephemeral key for:")
console.log(user)

//Create ephemeral key
stripe.ephemeralKeys.create(
{customer: user.customerid },
{stripe_version: '2018-11-08'}
)
.then((key) => {
console.log(key)
console.log("Succesful path. Ephemeral created.")
return "Testing"
})
.catch((err) => {
console.log("Unsuccesful path. Ephemeral not created.")
console.log(err)
return {
valid: false,
data: "Error creating Stripe key"
}
})
})
})


Client-side:



  functions.httpsCallable("stripeEphemeralKey").call(["text": "Testing"]) { (result, error) in
print(result?.data)
}


I have tested this code by replacing the body of the stripeEphemeralKey with a simple "Testing" string and that returns just fine. But with the code above I just get Optional() back.



For testing I added lots of console logs. Firebase logs show the execution path gets to the "Succesful path. Ephemeral created." log, and furthermore I can actually see the ephemeral key I get back from stripe.



So, what is the proper correct way to get the ephemeral key in Swift for iOS using the onCall Firebase function?



The backend does what it should, but I can't seem to get the answer back.



Thank you.










share|improve this question





























    1















    I've been playing around with stripe and would like to learn how to get ephemeral keys in the following way:



    Back-end:



    //Stripe API requirement for payment
    exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
    const uid = context.auth.uid;

    //Get values
    admin.database().ref().child("users").child(uid)
    .on("value", (snapshot) =>{
    //Get user data
    let user = snapshot.val()

    //Log data
    console.log("Create ephemeral key for:")
    console.log(user)

    //Create ephemeral key
    stripe.ephemeralKeys.create(
    {customer: user.customerid },
    {stripe_version: '2018-11-08'}
    )
    .then((key) => {
    console.log(key)
    console.log("Succesful path. Ephemeral created.")
    return "Testing"
    })
    .catch((err) => {
    console.log("Unsuccesful path. Ephemeral not created.")
    console.log(err)
    return {
    valid: false,
    data: "Error creating Stripe key"
    }
    })
    })
    })


    Client-side:



      functions.httpsCallable("stripeEphemeralKey").call(["text": "Testing"]) { (result, error) in
    print(result?.data)
    }


    I have tested this code by replacing the body of the stripeEphemeralKey with a simple "Testing" string and that returns just fine. But with the code above I just get Optional() back.



    For testing I added lots of console logs. Firebase logs show the execution path gets to the "Succesful path. Ephemeral created." log, and furthermore I can actually see the ephemeral key I get back from stripe.



    So, what is the proper correct way to get the ephemeral key in Swift for iOS using the onCall Firebase function?



    The backend does what it should, but I can't seem to get the answer back.



    Thank you.










    share|improve this question



























      1












      1








      1








      I've been playing around with stripe and would like to learn how to get ephemeral keys in the following way:



      Back-end:



      //Stripe API requirement for payment
      exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
      const uid = context.auth.uid;

      //Get values
      admin.database().ref().child("users").child(uid)
      .on("value", (snapshot) =>{
      //Get user data
      let user = snapshot.val()

      //Log data
      console.log("Create ephemeral key for:")
      console.log(user)

      //Create ephemeral key
      stripe.ephemeralKeys.create(
      {customer: user.customerid },
      {stripe_version: '2018-11-08'}
      )
      .then((key) => {
      console.log(key)
      console.log("Succesful path. Ephemeral created.")
      return "Testing"
      })
      .catch((err) => {
      console.log("Unsuccesful path. Ephemeral not created.")
      console.log(err)
      return {
      valid: false,
      data: "Error creating Stripe key"
      }
      })
      })
      })


      Client-side:



        functions.httpsCallable("stripeEphemeralKey").call(["text": "Testing"]) { (result, error) in
      print(result?.data)
      }


      I have tested this code by replacing the body of the stripeEphemeralKey with a simple "Testing" string and that returns just fine. But with the code above I just get Optional() back.



      For testing I added lots of console logs. Firebase logs show the execution path gets to the "Succesful path. Ephemeral created." log, and furthermore I can actually see the ephemeral key I get back from stripe.



      So, what is the proper correct way to get the ephemeral key in Swift for iOS using the onCall Firebase function?



      The backend does what it should, but I can't seem to get the answer back.



      Thank you.










      share|improve this question
















      I've been playing around with stripe and would like to learn how to get ephemeral keys in the following way:



      Back-end:



      //Stripe API requirement for payment
      exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
      const uid = context.auth.uid;

      //Get values
      admin.database().ref().child("users").child(uid)
      .on("value", (snapshot) =>{
      //Get user data
      let user = snapshot.val()

      //Log data
      console.log("Create ephemeral key for:")
      console.log(user)

      //Create ephemeral key
      stripe.ephemeralKeys.create(
      {customer: user.customerid },
      {stripe_version: '2018-11-08'}
      )
      .then((key) => {
      console.log(key)
      console.log("Succesful path. Ephemeral created.")
      return "Testing"
      })
      .catch((err) => {
      console.log("Unsuccesful path. Ephemeral not created.")
      console.log(err)
      return {
      valid: false,
      data: "Error creating Stripe key"
      }
      })
      })
      })


      Client-side:



        functions.httpsCallable("stripeEphemeralKey").call(["text": "Testing"]) { (result, error) in
      print(result?.data)
      }


      I have tested this code by replacing the body of the stripeEphemeralKey with a simple "Testing" string and that returns just fine. But with the code above I just get Optional() back.



      For testing I added lots of console logs. Firebase logs show the execution path gets to the "Succesful path. Ephemeral created." log, and furthermore I can actually see the ephemeral key I get back from stripe.



      So, what is the proper correct way to get the ephemeral key in Swift for iOS using the onCall Firebase function?



      The backend does what it should, but I can't seem to get the answer back.



      Thank you.







      ios swift typescript firebase google-cloud-functions






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '18 at 20:11







      ReverseFlow

















      asked Nov 13 '18 at 18:49









      ReverseFlowReverseFlow

      202311




      202311
























          2 Answers
          2






          active

          oldest

          votes


















          2














          The backend does not actually do what it should do. You're doing at least two things wrong here.



          First, your callable function needs to return a promise that resolves with the value that you want to send to the client. Right now, your function callback isn't returning anything at all, which means the client won't receive anything. You have return values inside promise handlers, but you need a top-level return statement.



          Second, you're using on() to read data from Realtime Database, which attaches a listener that persists until it's removed. This is almost certainly never what you want to do in a Cloud Function. Instead, use once() to get a single snapshot of the data you want to read, and act on that.






          share|improve this answer
























          • HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

            – ReverseFlow
            Nov 13 '18 at 19:28











          • I updated the original question in response to your suggestion. Please take a look.

            – ReverseFlow
            Nov 13 '18 at 19:32











          • It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

            – Doug Stevenson
            Nov 13 '18 at 20:03











          • Got it. I will edit back to the original question and try to fix that. Thanks.

            – ReverseFlow
            Nov 13 '18 at 20:10



















          0














          For my own reference, and those who might find this helpful:



            //Stripe API requirement for payment
          exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
          const uid = context.auth.uid;

          return admin.database().ref().child("users").child(uid)
          .once("value", (snapshot) =>{
          console.log(snapshot.val() )
          })
          .then( (snap) => {
          const customer = snap.val()

          //Log data
          console.log("Create ephemeral key for:")
          console.log(customer)

          //Create ephemeral key
          return stripe.ephemeralKeys.create(
          {customer: customer.customerid },
          {stripe_version: '2018-11-08'}
          )
          .then((key) => {
          console.log(key)
          console.log("Succesful path. Ephemeral created.")
          return {
          valid: true,
          data: key
          }
          })
          .catch((err) => {
          console.log("Unsuccesful path. Ephemeral not created.")
          console.log(err)
          return {
          valid: false,
          data: "Error creating Stripe key"
          }
          })
          })
          .catch( err => {
          console.log("Unsuccesful path. Ephemeral not created.")
          console.log(err)
          return {
          valid: false,
          data: "Error gettting customerid"
          }
          })
          })


          The key seems to be to chain the initial database request with .then(), and do our our work chaining the returns uninterrupted as we use functions that return promises. In particular, placing my work-code inside the callback on the original admin.database().ref().once() function did not work for me.



          I am new to this kind of programming, so someone who knows about this might the why better.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287678%2fhow-to-received-promises-from-backend-in-firebase-httpscallable-call%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            The backend does not actually do what it should do. You're doing at least two things wrong here.



            First, your callable function needs to return a promise that resolves with the value that you want to send to the client. Right now, your function callback isn't returning anything at all, which means the client won't receive anything. You have return values inside promise handlers, but you need a top-level return statement.



            Second, you're using on() to read data from Realtime Database, which attaches a listener that persists until it's removed. This is almost certainly never what you want to do in a Cloud Function. Instead, use once() to get a single snapshot of the data you want to read, and act on that.






            share|improve this answer
























            • HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

              – ReverseFlow
              Nov 13 '18 at 19:28











            • I updated the original question in response to your suggestion. Please take a look.

              – ReverseFlow
              Nov 13 '18 at 19:32











            • It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

              – Doug Stevenson
              Nov 13 '18 at 20:03











            • Got it. I will edit back to the original question and try to fix that. Thanks.

              – ReverseFlow
              Nov 13 '18 at 20:10
















            2














            The backend does not actually do what it should do. You're doing at least two things wrong here.



            First, your callable function needs to return a promise that resolves with the value that you want to send to the client. Right now, your function callback isn't returning anything at all, which means the client won't receive anything. You have return values inside promise handlers, but you need a top-level return statement.



            Second, you're using on() to read data from Realtime Database, which attaches a listener that persists until it's removed. This is almost certainly never what you want to do in a Cloud Function. Instead, use once() to get a single snapshot of the data you want to read, and act on that.






            share|improve this answer
























            • HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

              – ReverseFlow
              Nov 13 '18 at 19:28











            • I updated the original question in response to your suggestion. Please take a look.

              – ReverseFlow
              Nov 13 '18 at 19:32











            • It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

              – Doug Stevenson
              Nov 13 '18 at 20:03











            • Got it. I will edit back to the original question and try to fix that. Thanks.

              – ReverseFlow
              Nov 13 '18 at 20:10














            2












            2








            2







            The backend does not actually do what it should do. You're doing at least two things wrong here.



            First, your callable function needs to return a promise that resolves with the value that you want to send to the client. Right now, your function callback isn't returning anything at all, which means the client won't receive anything. You have return values inside promise handlers, but you need a top-level return statement.



            Second, you're using on() to read data from Realtime Database, which attaches a listener that persists until it's removed. This is almost certainly never what you want to do in a Cloud Function. Instead, use once() to get a single snapshot of the data you want to read, and act on that.






            share|improve this answer













            The backend does not actually do what it should do. You're doing at least two things wrong here.



            First, your callable function needs to return a promise that resolves with the value that you want to send to the client. Right now, your function callback isn't returning anything at all, which means the client won't receive anything. You have return values inside promise handlers, but you need a top-level return statement.



            Second, you're using on() to read data from Realtime Database, which attaches a listener that persists until it's removed. This is almost certainly never what you want to do in a Cloud Function. Instead, use once() to get a single snapshot of the data you want to read, and act on that.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 '18 at 19:15









            Doug StevensonDoug Stevenson

            75.2k988107




            75.2k988107













            • HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

              – ReverseFlow
              Nov 13 '18 at 19:28











            • I updated the original question in response to your suggestion. Please take a look.

              – ReverseFlow
              Nov 13 '18 at 19:32











            • It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

              – Doug Stevenson
              Nov 13 '18 at 20:03











            • Got it. I will edit back to the original question and try to fix that. Thanks.

              – ReverseFlow
              Nov 13 '18 at 20:10



















            • HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

              – ReverseFlow
              Nov 13 '18 at 19:28











            • I updated the original question in response to your suggestion. Please take a look.

              – ReverseFlow
              Nov 13 '18 at 19:32











            • It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

              – Doug Stevenson
              Nov 13 '18 at 20:03











            • Got it. I will edit back to the original question and try to fix that. Thanks.

              – ReverseFlow
              Nov 13 '18 at 20:10

















            HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

            – ReverseFlow
            Nov 13 '18 at 19:28





            HI Doug, I've watched every one of your videos. Helpful, but make more of them! :P

            – ReverseFlow
            Nov 13 '18 at 19:28













            I updated the original question in response to your suggestion. Please take a look.

            – ReverseFlow
            Nov 13 '18 at 19:32





            I updated the original question in response to your suggestion. Please take a look.

            – ReverseFlow
            Nov 13 '18 at 19:32













            It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

            – Doug Stevenson
            Nov 13 '18 at 20:03





            It looks like you now have a completely different set of problems than you originally had. This sounds like a second question to me (Stack Overflow isn't a place to go back and forth on a series of issues or get debugging help).

            – Doug Stevenson
            Nov 13 '18 at 20:03













            Got it. I will edit back to the original question and try to fix that. Thanks.

            – ReverseFlow
            Nov 13 '18 at 20:10





            Got it. I will edit back to the original question and try to fix that. Thanks.

            – ReverseFlow
            Nov 13 '18 at 20:10













            0














            For my own reference, and those who might find this helpful:



              //Stripe API requirement for payment
            exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
            const uid = context.auth.uid;

            return admin.database().ref().child("users").child(uid)
            .once("value", (snapshot) =>{
            console.log(snapshot.val() )
            })
            .then( (snap) => {
            const customer = snap.val()

            //Log data
            console.log("Create ephemeral key for:")
            console.log(customer)

            //Create ephemeral key
            return stripe.ephemeralKeys.create(
            {customer: customer.customerid },
            {stripe_version: '2018-11-08'}
            )
            .then((key) => {
            console.log(key)
            console.log("Succesful path. Ephemeral created.")
            return {
            valid: true,
            data: key
            }
            })
            .catch((err) => {
            console.log("Unsuccesful path. Ephemeral not created.")
            console.log(err)
            return {
            valid: false,
            data: "Error creating Stripe key"
            }
            })
            })
            .catch( err => {
            console.log("Unsuccesful path. Ephemeral not created.")
            console.log(err)
            return {
            valid: false,
            data: "Error gettting customerid"
            }
            })
            })


            The key seems to be to chain the initial database request with .then(), and do our our work chaining the returns uninterrupted as we use functions that return promises. In particular, placing my work-code inside the callback on the original admin.database().ref().once() function did not work for me.



            I am new to this kind of programming, so someone who knows about this might the why better.






            share|improve this answer




























              0














              For my own reference, and those who might find this helpful:



                //Stripe API requirement for payment
              exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
              const uid = context.auth.uid;

              return admin.database().ref().child("users").child(uid)
              .once("value", (snapshot) =>{
              console.log(snapshot.val() )
              })
              .then( (snap) => {
              const customer = snap.val()

              //Log data
              console.log("Create ephemeral key for:")
              console.log(customer)

              //Create ephemeral key
              return stripe.ephemeralKeys.create(
              {customer: customer.customerid },
              {stripe_version: '2018-11-08'}
              )
              .then((key) => {
              console.log(key)
              console.log("Succesful path. Ephemeral created.")
              return {
              valid: true,
              data: key
              }
              })
              .catch((err) => {
              console.log("Unsuccesful path. Ephemeral not created.")
              console.log(err)
              return {
              valid: false,
              data: "Error creating Stripe key"
              }
              })
              })
              .catch( err => {
              console.log("Unsuccesful path. Ephemeral not created.")
              console.log(err)
              return {
              valid: false,
              data: "Error gettting customerid"
              }
              })
              })


              The key seems to be to chain the initial database request with .then(), and do our our work chaining the returns uninterrupted as we use functions that return promises. In particular, placing my work-code inside the callback on the original admin.database().ref().once() function did not work for me.



              I am new to this kind of programming, so someone who knows about this might the why better.






              share|improve this answer


























                0












                0








                0







                For my own reference, and those who might find this helpful:



                  //Stripe API requirement for payment
                exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
                const uid = context.auth.uid;

                return admin.database().ref().child("users").child(uid)
                .once("value", (snapshot) =>{
                console.log(snapshot.val() )
                })
                .then( (snap) => {
                const customer = snap.val()

                //Log data
                console.log("Create ephemeral key for:")
                console.log(customer)

                //Create ephemeral key
                return stripe.ephemeralKeys.create(
                {customer: customer.customerid },
                {stripe_version: '2018-11-08'}
                )
                .then((key) => {
                console.log(key)
                console.log("Succesful path. Ephemeral created.")
                return {
                valid: true,
                data: key
                }
                })
                .catch((err) => {
                console.log("Unsuccesful path. Ephemeral not created.")
                console.log(err)
                return {
                valid: false,
                data: "Error creating Stripe key"
                }
                })
                })
                .catch( err => {
                console.log("Unsuccesful path. Ephemeral not created.")
                console.log(err)
                return {
                valid: false,
                data: "Error gettting customerid"
                }
                })
                })


                The key seems to be to chain the initial database request with .then(), and do our our work chaining the returns uninterrupted as we use functions that return promises. In particular, placing my work-code inside the callback on the original admin.database().ref().once() function did not work for me.



                I am new to this kind of programming, so someone who knows about this might the why better.






                share|improve this answer













                For my own reference, and those who might find this helpful:



                  //Stripe API requirement for payment
                exports.stripeEphemeralKey = functions.https.onCall((data, context) => {
                const uid = context.auth.uid;

                return admin.database().ref().child("users").child(uid)
                .once("value", (snapshot) =>{
                console.log(snapshot.val() )
                })
                .then( (snap) => {
                const customer = snap.val()

                //Log data
                console.log("Create ephemeral key for:")
                console.log(customer)

                //Create ephemeral key
                return stripe.ephemeralKeys.create(
                {customer: customer.customerid },
                {stripe_version: '2018-11-08'}
                )
                .then((key) => {
                console.log(key)
                console.log("Succesful path. Ephemeral created.")
                return {
                valid: true,
                data: key
                }
                })
                .catch((err) => {
                console.log("Unsuccesful path. Ephemeral not created.")
                console.log(err)
                return {
                valid: false,
                data: "Error creating Stripe key"
                }
                })
                })
                .catch( err => {
                console.log("Unsuccesful path. Ephemeral not created.")
                console.log(err)
                return {
                valid: false,
                data: "Error gettting customerid"
                }
                })
                })


                The key seems to be to chain the initial database request with .then(), and do our our work chaining the returns uninterrupted as we use functions that return promises. In particular, placing my work-code inside the callback on the original admin.database().ref().once() function did not work for me.



                I am new to this kind of programming, so someone who knows about this might the why better.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 13 '18 at 21:42









                ReverseFlowReverseFlow

                202311




                202311






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287678%2fhow-to-received-promises-from-backend-in-firebase-httpscallable-call%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Full-time equivalent

                    Bicuculline

                    さくらももこ