Firebase 云函数错误:函数返回未定义、预期的 Promise 或值

Posted

技术标签:

【中文标题】Firebase 云函数错误:函数返回未定义、预期的 Promise 或值【英文标题】:Firebase cloud function error: Function returned undefined, expected Promise or value 【发布时间】:2018-12-03 04:32:17 【问题描述】:

我已经定义了一个 Firebase 云函数,它在实时数据库 onCreate 触发器上执行。该函数完美地执行了它的预期算法,除了日志总是显示错误:Function returned undefined, expected Promise or value。我已经尝试了很多东西,但我仍然无法消除该错误。代码的重要sn-ps如下。

我已经正确地返回了一个承诺。任何想法如何使错误消失?

index.js

const sendNotificationMessageModule = require('./sendNotificationMessage');

exports.sendNotificationMessage = functions.database.ref( '/Notifications/pushId').onCreate((snapshot, context) => 
  sendNotificationMessageModule.sendNotificationMessage(snapshot, context, db, admin);
);

sendNotificationMessage.js

代码的第一部分:

exports.sendNotificationMessage = function(snapshot, context, db, admin) 
.
.
.

代码的最后部分:

        if(...) 
        .
        .
        .
          var androidNode = ;
          androidNode[constants.propertyNotificationString] = notificationNode;
          message[constants.propertyAndroidString] = androidNode;

          return admin.messaging().send(message)
          .then((response) => 
            console.log('Successfully sent message:', response);
            return snapshotNotificationMessage.ref.remove();
          )
          .catch((error) => 
            console.log('Error sending message:', error);
          );
        

如您所见,消息发送成功,但错误仍然存​​在。 当然,实时数据库中的数据也被成功删除了。

【问题讨论】:

发布代码时,请发布整个函数,而不仅仅是函数体。看看它是什么样的云功能非常重要。 嗨,我看了你的视频!它们对理解承诺非常有帮助。我没有发布整个代码,因为它太长了!所以我只发布了它的结尾部分。该函数是一个实时数据库触发器onCreate,它成功执行了发送消息,但函数仍然退出并出现上述错误。我现在发布第一部分和最后一部分。 【参考方案1】:

Cloud Functions for Firebase 由后台事件触发必须返回一个承诺(或者在某些情况下是一个值,例如return false;)。

由于admin.messaging().send()返回一个promise(见doc),你只需要返回这个promise,如下:

var androidNode = ;
androidNode[constants.propertyNotificationString] = notificationNode;
message[constants.propertyAndroidString] = androidNode;
....
return admin.messaging().send(message);
)
.catch((error) => 
    console.log('Error sending message:', error);
    return false;
);

然而,你也调用了snapshotNotificationMessage.ref.remove();,它也返回了一个promise。因此,您应该在您的云函数中链接这些承诺。这应该可能按如下方式完成,但如果没有完整的代码,很难保证这是 100% 正确的。如果您将整个代码添加到您的问题中,我们可能会对其进行调整。

....
    var androidNode = ;
    androidNode[constants.propertyNotificationString] = notificationNode;
    message[constants.propertyAndroidString] = androidNode;
    return snapshotNotificationMessage.ref.remove();
.then(() => 
    return admin.messaging().send(message);
)
.catch((error) => 
    console.log('Error sending message:', error);
    return false;
);

此外,我建议您观看 Firebase 团队的这两个视频,其中解释了为什么以及如何返回承诺:

https://www.youtube.com/watch?v=7IkUgCLr5oA

https://www.youtube.com/watch?v=652XeeKNHSk

第一个更多关于通过 HTTP 请求触发的 HTTP 函数(因此不是通过后台事件),而第二个侧重于背景事件触发的函数,但建议先看第一个,然后再看第二个一个。

【讨论】:

谢谢,我会测试你建议的答案.. 并观看视频。如果它有效或无效,我会回复你。 我观看了视频,它们非常有帮助,但我仍然遇到错误。 -_-; 请将整个云函数代码添加到您的Pots中,而不仅仅是sn-ps。 我修改了我的问题并添加了云功能日志的帖子和截图。希望修改使我的问题更清楚。谢谢!【参考方案2】:

您将返回以返回 sendNotificationMessage 返回的承诺。这就是 Cloud Functions 知道所有异步工作何时完成的方式:

const sendNotificationMessageModule = require('./sendNotificationMessage');

exports.sendNotificationMessage = functions.database.ref( '/Notifications/pushId').onCreate((snapshot, context) => 
  return sendNotificationMessageModule.sendNotificationMessage(snapshot, context, db, admin);
);

【讨论】:

天哪,我怎么忽略了这一点?!但无论如何,我在父函数中添加了return,但错误仍然存​​在。 >_ 好吧,既然你没有展示所有的代码,所以不可能确定。通常,在 Stack Overflow 上,您提供一个 MCVE 来帮助每个人都能够准确地重现您遇到的问题。 ***.com/help/mcve 我创建了一个 testFunction exports.testFunction = functions.database.ref('/test/pushId').onCreate((snapshot, context) => return snapshot.ref.remove() .then(function() console.log("successfully removed"); return true; ); ); 并且它没有返回任何错误。所以我怀疑发送函数没有正确返回承诺。 但是您询问的代码与您刚刚在评论中发布的代码不同。编辑您的问题以包含显示问题的最少、完整的代码。 我很抱歉上面的评论。你说的对!!!我再次查看了我的整个代码,并在我的数据库引用中使用了一次函数,但我没有在其中使用 Promise,而是使用了旧的回调方法。我现在将所有内容都转换为承诺,并且成功了!!!!没有更多的错误!但是我需要重构我的代码,这样我就不会嵌套承诺。我还需要以这样一种方式重构它,即承诺链是顺序的,因为我需要一个承诺来运行另一个承诺。非常感谢您的坚持!

以上是关于Firebase 云函数错误:函数返回未定义、预期的 Promise 或值的主要内容,如果未能解决你的问题,请参考以下文章

函数返回未定义、预期的 Promise 或值 Firebase 日志错误

函数返回未定义,预期Promise或值和通知长时间延迟

firebase云函数错误TypeError:无法读取未定义的属性“子”

Firebase 云函数对象可能“未定义”

Firebase firestore 云函数显示错误:无效使用类型“未定义”作为 Firestore 参数

Firebase 函数在本地提供时未返回预期的环境配置