Firestore触发Cloud Function推送通知失败求助:代码错误排查
排查Firestore触发的Cloud Function推送通知失败问题
我帮你梳理下代码里的几个关键问题,这些应该是导致通知无法正常送达的核心原因:
1. 语法错误:Payload对象未正确闭合
在enviaMensage函数中,你定义完payload对象后直接开始写获取token的逻辑,但payload的大括号没有闭合——这会直接导致函数运行抛出语法错误,根本走不到发送通知的步骤。
2. 未等待异步函数执行完成
你的enviaMensage是异步函数,但在cambiaColeccion里调用它时没有加await。Cloud Function的生命周期会在同步代码执行完后就结束,不会等待未被await的异步任务完成,所以通知发送逻辑可能还没执行就被终止了。
3. 可选优化:利用传入的文档数据(非错误原因)
你已经获取了snap.data()里的titulo字段,但当前代码里的通知标题是硬编码的。如果需要动态设置通知内容,可以把payload里的标题替换成nuevoMensaje.titulo。
修正后的完整代码
exports.cambiaColeccion = functions.firestore .document('sendMessage/{docId}') .onCreate(async (snap, context) => { // 添加async,支持内部await调用 const nuevoMensaje= snap.data(); console.log('id', nuevoMensaje); console.log('titulo', nuevoMensaje.titulo) await enviaMensage(nuevoMensaje); // 加await确保异步任务执行完成,同时传入文档数据 }); async function enviaMensage(nuevoMensaje) { console.log('en enviaMensaje'); const payload ={ notification: { title: nuevoMensaje?.titulo || "Titulo del mensaje", // 动态使用传入的标题,兼容空值场景 body: "Texto del mensaje ... ", sound: 'default', badge: '1', } }; // 补上缺失的大括号,闭合payload对象 // Get the list of device tokens. const allTokens = await admin.firestore().collection('FCMTokens').get(); const tokens = []; allTokens.forEach((tokenDoc) => { tokens.push(tokenDoc.id); }); if (tokens.length > 0) { // Send notifications to all tokens. const response = await admin.messaging().sendToDevice(tokens, payload); await cleanupTokens(response, tokens); // 恢复无效token清理逻辑 console.log('Notifications have been sent and tokens cleaned up.'); } return true; } // Cleans up the tokens that are no longer valid. function cleanupTokens(response, tokens) { // For each notification we check if there was an error. const tokensDelete = []; response.results.forEach((result, index) => { const error = result.error; if (error) { console.error('Failure sending notification to', tokens[index], error); // Cleanup the tokens who are not registered anymore. if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') { const deleteTask = admin.firestore().collection('FCMTokens').doc(tokens[index]).delete(); tokensDelete.push(deleteTask); } } }); return Promise.all(tokensDelete); }
额外检查项
- 确保你的Cloud Function服务账号拥有
cloudmessaging.messages.create权限,以及Firestore的读取权限 - 确认
FCMTokens集合里存储的token是有效的设备注册令牌,没有过期或被注销 - 查看Cloud Function的日志(通过GCP控制台),可以看到具体的错误信息,帮助进一步排查
内容的提问来源于stack exchange,提问作者Marcos Galaviz
相关产品推荐
相关产品推荐

