Flutter应用无法接收Firebase Cloud Functions发送的FCM通知求助
问题原因
- 异步逻辑未正确等待:代码中的Firestore查询、FCM发送都属于异步操作,当前代码没有等待这些操作执行完成就调用了
response.send()并返回,Cloud Functions会在函数返回后立即冻结运行环境,绝大多数情况下后续的FCM发送逻辑会被中断,你看到的日志只是在实例冻结前刚好执行完成的部分,实际通知并没有被完整投递。 - FCM payload缺少平台必填配置:Flutter应用接收FCM通知时,针对不同系统需要补充专属配置,Android 8.0及以上版本要求通知必须指定渠道ID,iOS端需要配置APNs相关参数才能正常显示通知,你当前的payload仅包含通用通知字段,缺少平台适配项。
- 错误未被捕获排查:当前代码中FCM发送的错误捕获逻辑仅返回了错误对象,没有打印到云日志中,你看不到实际投递过程中出现的token无效、权限不足等问题。
解决方法
1. 修正异步逻辑,确保操作全部完成后再返回
你可以用Promise.all包裹所有FCM发送任务,等待所有任务执行完成后再返回响应,修正后的代码示例如下:
exports.sendNotification = functions.https.onRequest(async (request, response) => { try { const db = admin.firestore(); const fcm = admin.messaging(); const result = await db.collection("users").where("bananas", "==", 1666).get(); const sendTasks = []; if (result.size > 0) { result.forEach((doc) => { const token = doc.data().NotToken; const payload = { token: token, notification: { title: "iam a notification", body: "Yay", icon: "https://cdn1.iconfinder.com/data/icons/logos-brands-in-colors/231/among-us-player-white-512.png", }, // 补充平台专属配置 android: { notification: { // 替换为你Flutter端注册的通知渠道ID channelId: "your_notification_channel_id", priority: "high" } }, apns: { payload: { aps: { sound: "default", contentAvailable: true } }, headers: { "apns-priority": "10" } } }; // 把发送任务加入数组,同时添加错误打印 const sendTask = fcm.send(payload) .then((res) => console.log(`发送成功,token:${token},消息ID:${res}`)) .catch((err) => console.error(`发送失败,token:${token},错误:${err.code}`, err)); sendTasks.push(sendTask); }); } // 等待所有发送任务完成 await Promise.all(sendTasks); functions.logger.info(`共处理${sendTasks.length}条通知发送任务`); response.send("Notification sent !"); } catch (e) { console.error("函数执行出错:", e); response.status(500).send("发送失败:" + e.message); } });
2. 检查Flutter端配置
- 确认Android端已经创建了和代码中
channelId一致的通知渠道 - 确认iOS端已经开启了推送通知、后台模式等相关权限
- 确认用户设备上传到Firestore的
NotToken是当前设备的有效FCM token,用户卸载重装应用后token会失效
3. 验证测试
修正代码部署后,先给单个测试设备的token发送通知,查看云日志中的错误输出,排查是否存在权限、token无效等问题。
内容的提问来源于stack exchange,提问作者Padi
相关产品推荐
相关产品推荐

