如何在 Firebase httpscallable().call() 中接收来自后端的承诺?

Posted

技术标签:

【中文标题】如何在 Firebase httpscallable().call() 中接收来自后端的承诺?【英文标题】:How to received promises from backend in Firebase httpscallable().call()? 【发布时间】:2018-11-13 18:49:43 【问题描述】:

我一直在玩 Stripe,想了解如何通过以下方式获取临时密钥:

后端:

//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"
      
    )
  )
)

客户端:

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

我已经通过用一个简单的“测试”字符串替换 stripeEphemeralKey 的主体来测试此代码,并且返回很好。但是使用上面的代码,我只是得到了 Optional() 。

为了测试,我添加了很多控制台日志。 Firebase 日志显示执行路径到达“成功路径。临时创建”。日志,此外,我实际上可以看到我从条带中返回的临时密钥。

那么,在 Swift for ios 中使用 onCall Firebase 函数获取临时密钥的正确正确方法是什么?

后端做了它应该做的,但我似乎无法得到答案。

谢谢。

【问题讨论】:

【参考方案1】:

后端实际上并没有做它应该做的事情。你在这里至少做错了两件事。

首先,您的可调用函数需要返回一个以您要发送给客户端的值解析的承诺。现在,您的函数回调根本没有返回任何内容,这意味着客户端不会收到任何内容。你在 Promise 处理程序中有返回值,但你需要一个***的 return 语句。

其次,您使用 on() 从实时数据库中读取数据,它附加了一个持续存在的侦听器,直到它被删除。这几乎肯定不是您想在云函数中做的事情。相反,请使用 once() 获取您要读取的数据的单个快照,然后对其进行操作。

【讨论】:

嗨,Doug,我看过你的每一部视频。有帮助,但要多做一些! :P 我根据您的建议更新了原始问题。请看一看。 看起来您现在遇到的问题与原来的完全不同。对我来说,这听起来像是第二个问题(Stack Overflow 不是一个在一系列问题上来回讨论或获得调试帮助的地方)。 知道了。我将编辑回原始问题并尝试解决该问题。谢谢。【参考方案2】:

供我自己参考,以及那些可能会觉得有帮助的人:

  //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"
    
  )
)

关键似乎是用 .then() 链接初始数据库请求,并在我们使用返回承诺的函数时不间断地链接返回。特别是,将我的工作代码放在原始 admin.database().ref().once() 函数的回调中对我不起作用。

我是这种编程的新手,所以知道这一点的人可能会更好。

【讨论】:

以上是关于如何在 Firebase httpscallable().call() 中接收来自后端的承诺?的主要内容,如果未能解决你的问题,请参考以下文章

Create React App 中 httpsCallable firebase 上的 CORS 错误

Firebase:如何调用 https.onCall 函数 node.js?

Firebase 可调用云函数 CORS 错误

如何使用 getHttpsCallable 方法检索数据

直接从firebase函数临时文件夹下载

为啥调用firebase函数时会出现FCM错误