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 我创建了一个 testFunctionexports.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 日志错误
firebase云函数错误TypeError:无法读取未定义的属性“子”