【问题标题】:firebase function for stripe webhook does not work with async-await条纹 webhook 的 firebase 功能不适用于 async-await
【发布时间】:2020-12-17 00:15:48
【问题描述】:

我正在使用优秀的stripe documentation 构建一个 webhook 来响应条带成功支付。代码运行良好,但是一旦我引入 async-await,我就会收到 500 内部服务器错误。

我正在通过 stripe 网站上的 send test webhook 测试 firebase onRequest webhook 功能。 我的代码存在于here

我错过了什么?

带有 async-await 的 firebase 功能不起作用:

exports.stripeEvents = functions.https.onRequest(async (request, response) => 
{
  try
  {    
    let stripesignature = request.headers['stripe-signature'] as string;
    let stripeevent:Stripe.Event= stripe.webhooks.constructEvent(request.rawBody.toString('utf8'), stripesignature, config.stripewebhooksecretkey);

    if(stripeevent.type === 'payment_intent.succeeded')
    {
      let payment_intent1 = stripeevent.data.object as Stripe.PaymentIntent;
      let datafirstelement=null;
      if(payment_intent1?.charges?.data && payment_intent1?.charges?.data.length>0)
      {
        datafirstelement=payment_intent1?.charges?.data[0];
      }        
      let userid='someuserid';
      let documentreference=config.db.collection('users').doc(userid);
      await documentreference.update({payments: admin.firestore.FieldValue.arrayUnion(datafirstelement)}); 
      response.status(200).send({'result':true});
    }
  }
  catch(error)
  {
    //log error into sentry
    throw error;
  }
});

没有 async-await 的 firebase 函数,有效:

exports.stripeEvents = functions.https.onRequest((request, response) => 
{
  try
  {    
    let stripesignature = request.headers['stripe-signature'] as string;
    let stripeevent:Stripe.Event= stripe.webhooks.constructEvent(request.rawBody.toString('utf8'), stripesignature, config.stripewebhooksecretkey);

    if(stripeevent.type === 'payment_intent.succeeded')
    {
      let payment_intent1 = stripeevent.data.object as Stripe.PaymentIntent;
      let datafirstelement=null;
      if(payment_intent1?.charges?.data && payment_intent1?.charges?.data.length>0)
      {
        datafirstelement=payment_intent1?.charges?.data[0];
      }        
      let userid='someuserid';
      let documentreference=config.db.collection('users').doc(userid);
      //await documentreference.update({payments: //admin.firestore.FieldValue.arrayUnion(datafirstelement)}); 
      response.status(200).send({'result':true});
    }
  }
  catch(error)
  {
    //log error into sentry
    throw error;
  }
});

更新1:我正在通过stripe网站上的send test webhook测试firebase onRequest webhook函数。

不使用 async-await 时条带支付成功,使用 async-await 时出现内部服务器错误:

不使用 async-await 时的 webhook 成功日志(使用 async-await 时没有日志):

更新 2:firebase 功能日志:

stripeEvents
Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.
    at Object.validateResourcePath (/workspace/node_modules/@google-cloud/firestore/build/src/path.js:403:15)
    at CollectionReference.doc (/workspace/node_modules/@google-cloud/firestore/build/src/reference.js:1988:20)
    at exports.stripeEvents.functions.https.onRequest (/workspace/lib/index.js:115:85)
    at cloudFunction (/workspace/node_modules/firebase-functions/lib/providers/https.js:51:16)
    at process.nextTick (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:99:17)
    at process._tickCallback (internal/process/next_tick.js:61:11)

更新 3:firebase 功能日志: 我将行 await documentreference.update({payments: //admin.firestore.FieldValue.arrayUnion(datafirstelement)}); 更改为 await documentreference.set({payments: admin.firestore.FieldValue.arrayUnion(datafirstelement)}, {merge:true}); 并且应用程序仍然抛出以下错误。代码位于here

12:02:30.464 AM
stripeEvents
Function execution started 
12:02:54.174 AM
stripeEvents
Function execution started 
12:02:54.901 AM
stripeEvents
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason: 
12:02:54.905 AM
stripeEvents
Function execution took 732 ms, finished with status: 'crash' 
12:03:30.467 AM
stripeEvents
Function execution took 60004 ms, finished with status: 'timeout' 

【问题讨论】:

  • 你的函数日志说问题是什么?请编辑问题以包含完整的错误及其所指的行。
  • 感谢@DougStevenson 的输入,我在问题中添加了更多详细信息。我的日志系统中没有记录任何错误,条带日志在尝试联系 firebase onRequest 函数时显示 500 内部服务器错误。
  • 对于您的 catch 块,您能否返回响应错误,例如 console.log(error) response.status(500).send({err: ${err}}) 您可能能够捕获错误并且最有可能抛出错误由documentreference.update()致电
  • 我指的是您的云功能日志,而不是条带。如果您的 javascript 抛出错误,日志应该有详细信息。
  • 谢谢@wsw,我正在将错误记录到哨兵中,但在哨兵中没有看到任何错误。就像您建议的那样(我在 firebase 函数日志中发现),这是一个与 documentreference.update() 调用相关的错误。我会调查的。

标签: node.js firebase async-await google-cloud-functions stripe-payments


【解决方案1】:

根据上面的 cmets 和您得到的错误 (Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.),您在测试 Cloud Function 时传递给 doc() 方法的值似乎是一个空字符串。

您需要在测试中模拟数据,以便将正确的值传递给 doc() 方法。


请注意,我不确定“从 Web 应用程序”测试它(正如您在上面的 cmets 中提到的)会改变什么,因为 Stripe Webhook 与您的 Web 应用程序无关(Stripe 后端调用您的后端,即您的云功能)。您可以将 userId 作为支付元数据发送到 Stripe,并 (1) 将其作为查询字符串参数添加到 webhook 调用的 URL 并 (2) 在您的 Cloud Function 中解析并使用该值。


另请注意,您的“异步版本”不起作用和您的“非异步版本”之间的区别与异步/等待无关,而只是您注释掉了生成错误的行。

【讨论】:

    猜你喜欢
    • 2018-03-24
    • 1970-01-01
    • 2019-10-24
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 2019-05-30
    • 2021-05-10
    相关资源
    最近更新 更多