【问题标题】:How to correctly return the result from Cloud Function?如何正确返回 Cloud Function 的结果?
【发布时间】:2021-09-21 06:31:35
【问题描述】:

我正在尝试使用 Cloud Function 和 Twilio 实现验证。 Twilio 工作正常,并且发送了带有代码的 SMS,但在 Flutter 应用程序中我收到错误 [firebase_functions/deadline-exceeded] DEADLINE_EXCEEDE。我做错了什么?

云功能:

const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);

exports.sendSms = (req, res) => {
  console.log('start sendSms');
  var func = client.verify.services('xxxxx')
    .verifications
    .create({to: req.body.data.phone, channel: 'sms'})
    .then(verification => {return verification})
    .then(result => {
      if (result.status === 'pending')
        return {status: 'success', result: "pending"};
      else
        return {status: 'error', error_code: -1, error_msg: result.status};
    })
    .catch(e => {
      return {status: 'error', error_code: e.code, error_msg: e.message};
    });

  return Promise.all([func]).then(result => {
    console.log(result); // console output [ { status: 'success', result: 'pending' } ]
    return result[0];
  });
};

颤动:

HttpsCallable callable = FirebaseFunctions.instanceFor(region: 'europe-west3').httpsCallable(
      'send-sms',
      options: HttpsCallableOptions(timeout: const Duration(seconds: 10))
);
dynamic results = await callable.call(<String, dynamic>{'phone': phoneNumber});

【问题讨论】:

  • 我在 Cloud 函数中看到了 Firestore 的此错误,但我在这里看不到任何与 Firestore 相关的代码。您是否在完整代码中偶然使用了 Firestore?
  • @Dharmaraj Firestore 已在应用程序中使用,但不在此场景中。错误恰好发生在调用“动态结果 = await callable.call ( {'phone': phoneNumber});”的地方。并且云端功能代码完整。
  • 那个功能完成了吗?如果不能,请分享您的完整代码并分享您的 Firebase 功能版本。我会尝试复制这个问题。
  • @Dharmaraj 感谢您愿意提供帮助。功能代码完整,只是服务标识替换为“xxxxx”,可惜出于安全原因无法提供原版。
  • 你累了吗return res.send("some data");你错过了完成响应,这不是关闭req-res周期。从而导致逾期。尝试return res.send(result[0]); 而不是return result[0];

标签: firebase flutter google-cloud-functions


【解决方案1】:

create 方法也返回 promise,所以你也必须在其中添加 return 关键字。

代替:

var func = client.verify.services('xxxxx')

试试这个:

exports.sendSms = functions.https.onCall((data, context) => {
                //^^^^^^^^^^^^^^^^^^^^^^
  console.log('start sendSms');
  return client.verify.services('xxxxx')
    .verifications
    .create({to: data.phone, channel: 'sms'})
    .then(verification => {return verification})
    .then(result => {
      if (result.status === 'pending')
        return {status: 'success', result: "pending"};
      else
        return {status: 'error', error_code: -1, error_msg: result.status};
    })
    .catch(e => {
      return {status: 'error', error_code: e.code, error_msg: e.message};
    });
});

也就是说你不需要这部分:

return Promise.all([func]).then(result => {
    console.log(result); // console output [ { status: 'success', result: 'pending' } ]
    return result[0];
  });

【讨论】:

  • 我最初按照您的建议尝试了(即代码中没有Promise),但是出现了同样的错误,所以我尝试添加一个Promise,但错误仍然存​​在。
  • @ecywyv 我不明白你为什么有那个额外的 .then 返回验证。
  • 这个是不小心留下的,你是对的,那么这个是多余的,去掉它,但不影响结果
  • @ecywyv 一开始似乎不是云功能
  • @ecywyv 很高兴它得到了解决。关于 onCall 和 onRequest 区别的详细信息可以参考文档中的call functions from your app部分。
【解决方案2】:

您在客户端应用中使用 Firebase 函数“可调用”类型的函数,但它与后端的可调用类型函数不匹配。您不能使用 Firebase SDK 调用正常的 HTTP 类型函数。它只是不起作用。

如果你想使用客户端的可调用函数,你必须在后端编写一个可调用函数。你应该阅读上面的documentation。它有一个特殊的protocol,必须在通话的两端观察到。

如果您在后端编写一个普通的 HTTP 函数,那么只需在前端选择一个普通的 HTTP 客户端库,而不是 Firebase SDK。

【讨论】:

  • 所以这个答案对你没有帮助?
  • 你的问题是“我做错了什么”,在这里得到了回答。不清楚您要做什么-您是在尝试编写可调用函数,还是在尝试编写 HTTP 函数?无法判断。
  • 您的回答是我的问题的解决方案,我感谢您并用解决方案对其进行了标记,但由于某种原因,该网站本身删除了我所有的 cmets,并在每个答案下都表示感谢,并且两个答案不能表示为解决方案,因此,很可能作为解决方案检查了我指出的最后一个答案。再次感谢(希望评论不要再被删除)。
  • Stack Overflow 习惯于对有用的答案进行投票,即使您无法将它们标记为正确。您可以根据自己的问题为任意数量的答案投票。
  • 我尝试这样做,但由于我是该网站的新手,所以我错过了评级。 (我收到消息“您需要至少 15 声望才能投票”)
猜你喜欢
  • 1970-01-01
  • 2019-05-23
  • 2012-04-11
  • 2016-04-08
  • 2016-02-06
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多