Firebase Cloud Functions触发返回undefined,期望Promise或值如何解决
问题根因
该报错的核心原因是Firebase Cloud Functions要求触发器回调必须返回一个Promise或者明确的返回值,你当前代码没有返回Firestore查询的Promise链,函数同步执行到末尾直接返回undefined,就会抛出Function returned undefined, expected Promise or value的错误,即使最终显示状态为ok,也可能出现异步逻辑未执行完成就被回收的问题。
此外代码还存在两个会导致推送发送失败的隐藏问题:
- 嵌套的
admin.messaging().sendToDevice()异步调用没有被返回,外层Promise会提前resolve,函数实例可能在推送请求发出前就被销毁 - API参数使用错误:你写的payload格式是
admin.messaging().send()方法的入参格式,而sendToDevice方法要求第一个参数传设备token,第二个参数才是通知配置
修正后的代码(保持then链写法)
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.updateOrderStatus = functions.firestore .document("Users/{userId}/Info_Notifications/{notificationId}") .onUpdate((change, context) => { const newValue = change.after.data(); const notificationFor = newValue.orderFrom; const db = admin.firestore(); // 这里加return,把整个Promise链返回给Function return db.collection("Tokens").doc(notificationFor).get() .then((doc) => { // 补充doc存在性判断,避免空值报错 if (!doc.exists) { console.log("找不到对应用户的token文档"); return null; } const user = doc.data(); const deviceID = user.id; console.log("Device id", deviceID); const payload = { token: deviceID, notification: { title: "Test Notification", body: "message", }, data: { priority: "high", timeToLive: "60 * 60* 24", }, }; // 这里返回send的Promise加入链中,换成send方法适配你写的payload格式 return admin.messaging().send(payload) .then((response) => { console.log("推送发送成功", response); return true; }) .catch((error) => { console.log("Error Sending Notifications", error); return false; }); }).catch((error) => { console.log("Error in fetching data", error); return false; }); });
更易维护的async/await写法参考
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.updateOrderStatus = functions.firestore .document("Users/{userId}/Info_Notifications/{notificationId}") .onUpdate(async (change, context) => { try { const newValue = change.after.data(); const notificationFor = newValue.orderFrom; const db = admin.firestore(); const doc = await db.collection("Tokens").doc(notificationFor).get(); if (!doc.exists) { console.log("找不到对应用户的token文档"); return null; } const user = doc.data(); const deviceID = user.id; console.log("Device id", deviceID); const payload = { token: deviceID, notification: { title: "Test Notification", body: "message", }, data: { priority: "high", timeToLive: "60 * 60* 24", }, }; const response = await admin.messaging().send(payload); console.log("推送发送成功", response); return true; } catch (error) { console.log("执行出错", error); return false; } });
内容的提问来源于stack exchange,提问作者jigexi
相关产品推荐
相关产品推荐

