Firestore云函数在模拟器运行正常但部署后无推送效果如何解决
问题原因
- 异步操作未被等待:
admin.messaging().send()是异步方法,使用forEach遍历执行时,云函数不会等待所有异步请求执行完成就会终止进程。本地模拟器不会立刻销毁运行进程,所以任务能跑完;生产环境执行到函数末尾就会直接回收资源,未完成的消息发送逻辑就会被中断,自然没有相关日志输出。 - 条件判断匹配失效:新增的
statusValue == 0是非严格相等判断,本地测试用的activeUsers字段值为数字类型的0,但生产环境Firestore中存储的activeUsers对应值可能是字符串"0"、布尔值、甚至对应成员的key不存在返回undefined,都会导致判断不通过,跳过发送逻辑。
修复方案
- 先增加临时日志排查生产环境字段值:在
const statusValue = activeUsers[item]后增加一行console.log(成员${item}的active状态为, statusValue, '类型为', typeof statusValue),部署后看日志确认statusValue的实际值和类型,调整判断条件,建议改为严格相等===匹配对应类型的值。 - 替换forEach为Promise.all等待所有异步任务完成,保证所有消息发送逻辑执行完后云函数再终止。
修复后代码示例
const functions = require("firebase-functions"); const admin = require('firebase-admin'); admin.initializeApp(); // 群组新增消息时拉取群成员发送通知 exports.newMessage = functions.region('australia-southeast1') .firestore .document('ChatRooms/{chatRoomsID}/Messages/{messageID}') .onCreate(async (snap, context) => { const messageData = snap.data(); const messageSender = messageData.fullName; // 获取聊天群文档引用 const chatRoomRef = snap.ref.parent.parent; // 获取聊天群数据 const chatRoomSnap = await chatRoomRef.get(); const chatRoomData = chatRoomSnap.data(); const groupMembers = chatRoomData.members; const activeUsers = chatRoomData.activeUserStatus; const chatRoomTitle = chatRoomData.chatRoomTitle; const notificationTitle = `聊天群:${chatRoomTitle}` const notificationBody = `${messageSender}发送了一条消息`; // 用Promise.all收集所有异步任务等待执行完成 const sendTasks = []; for (const item of groupMembers) { const statusValue = activeUsers[item]; // 可先放开下面的日志排查生产环境的statusValue值 // console.log(`成员${item}的active状态为`, statusValue, '类型为', typeof statusValue); // 确认类型后改为严格相等,比如如果是数字0就写===0,如果是字符串"0"就写==="0" if (statusValue === 0) { const topic = item.replace(/[^a-zA-Z0-9]/g,'-'); const message = { notification : { title : notificationTitle, body: notificationBody }, apns: { payload: { aps: { sound : `default` } } }, topic: topic, }; // 将发送任务加入数组 sendTasks.push( admin.messaging().send(message) .then((response) => { console.log(`成功发送消息到${topic}`, response); }).catch((error) => { console.log('发送消息出错:', error); }) ); } } // 等待所有发送任务执行完成 await Promise.all(sendTasks); return; });
内容的提问来源于stack exchange,提问作者Osydon
相关产品推荐
相关产品推荐

