Firebase Cloud Messaging:消息丢失是否因限流机制导致?
FCM定时通知大量丢失的排查与分析
问题描述
我通过每10分钟触发的定时云函数发送FCM测试消息,但大量通知未送达设备。生成新令牌能暂时解决问题,但想知道是否是限流导致,以及怎么排查消息丢失的原因和位置。目前日志和发送仪表板都没有错误。
云函数代码
exports.kickOffUTCRemindersDue = onSchedule("*/10 * * * * ", async (event) => { // https://firebase.google.com/docs/cloud-messaging/send-message#send-messages-to-specific-devices const message = { notification: { title: "Hello World", body: "This is me calling", }, token: "TOKEN" }; getMessaging().send(message) .then((response) => { // Response is a message ID string. console.log('Successfully sent message:', response); }) .catch((error) => { console.log('Error sending message:', error); }); // response.json({ message: 'Hello from Firebase!' }); });
排查分析
一、是否由限流机制导致?
FCM确实存在限流策略,但限流时会返回明确的429 Too Many Requests错误,且日志或仪表板会有记录。你目前无报错信息,说明FCM服务器已接收请求,大概率不是限流直接导致的消息丢失,更可能是令牌有效性、设备端状态或投递环节的问题。
二、排查消息丢失的具体方法
1. 验证FCM令牌有效性
FCM令牌并非永久有效,设备重启、应用卸载重装、系统更新等操作都会导致令牌失效。旧令牌能被FCM接收但无法投递到设备,这也是你更换新令牌能暂时解决问题的核心原因。
- 调用
send接口时,即使整体请求成功,响应中也可能包含单个令牌的失效细节,需仔细解析返回值; - 查看Firebase控制台「云消息传递」模块的报告数据,对比发送量与设备接收量的差异,定位是否在投递环节丢失。
2. 检查设备端状态
- 离线状态:FCM仅会缓存消息最多4周,若设备长期离线,超出缓存时间的消息会被丢弃;
- 系统限制:安卓厂商的省电策略、iOS的后台刷新限制会阻止应用接收FCM通知,需确保应用已加入系统后台白名单;
- 客户端逻辑:检查设备端代码是否正确实现了FCM消息接收逻辑,特别是前台状态下是否手动处理通知展示。
3. 修复云函数代码漏洞
你的云函数是async函数,但调用getMessaging().send()时未使用await,会导致云函数在消息发送完成前就终止,可能中断请求流程。修改后的代码如下:
exports.kickOffUTCRemindersDue = onSchedule("*/10 * * * * ", async (event) => { const message = { notification: { title: "Hello World", body: "This is me calling", }, token: "TOKEN" }; try { const response = await getMessaging().send(message); console.log('Successfully sent message:', response); } catch (error) { console.log('Error sending message:', error); } });
添加await确保云函数等待消息发送完成后再结束,避免因函数提前终止导致的请求异常。
4. 启用全链路日志排查
- 服务端:在Firebase控制台开启FCM详细日志,查看消息从发送到投递的全链路状态;
- 客户端:安卓设备通过
adb logcat -s FirebaseMessaging查看FCM调试日志,iOS设备在Xcode控制台查看Firebase相关日志,确认设备是否接收到FCM消息。
内容的提问来源于stack exchange,提问作者udit
相关产品推荐
相关产品推荐

