Android应用FCM远程推送异常:飞行模式恢复后仅收最新通知求助
问题分析与解决方案
你遇到的核心问题是相同的collapse_key导致FCM自动合并了同组通知,再加上payload里的time_to_live位置错误,才会出现恢复网络后只收到最新一条的情况。我给你拆解下原因,再一步步说怎么改:
一、为什么会只收到最新通知?
collapse_key的误用:你给所有通知都用了同一个collapse_key: "deals",FCM的规则是——当设备离线时,同collapse_key的多条通知会被合并成一条,只保留最新的那条。不管你设置了多长的TTL,只要key相同,合并逻辑就会触发。time_to_live位置错误:你把time_to_live放在了data字段里,但FCM只会识别根级别的time_to_live参数,data里的这个字段对FCM来说只是自定义数据,不会生效。这导致离线时FCM可能没有按照你预期的时长缓存通知,进一步加剧了合并的问题。- AWS SNS的payload结构问题:虽然你外层用了
GCM字段,但内部的FCM控制参数(比如priority、time_to_live)必须放在根节点,不能嵌套在data里。
二、具体解决步骤
1. 给每条通知分配唯一的collapse_key
如果你希望所有通知都能被用户收到,不要给多条通知用同一个collapse_key。可以给每条通知生成一个唯一的key(比如包含通知ID、时间戳等),或者直接去掉这个字段(FCM会自动生成默认的key,不会合并通知)。
示例:
{ "GCM": "{ \"notification\": { \"text\": \"test 1\", \"title\": \"Titre 1\" }, \"data\": { \"custom_data\": \"your_data_here\" }, \"priority\": \"high\", \"time_to_live\": 3600, \"collapse_key\": \"deal-notification-1699999999\" // 唯一key }" }
2. 修正time_to_live的位置
把time_to_live从data字段移到FCM payload的根节点,这样FCM才会识别这个参数,在离线时按照设置的时长缓存通知。
3. 确认AWS SNS的推送格式
AWS SNS发送FCM通知时,外层的GCM字段必须是一个合法的JSON字符串,内部的FCM参数要严格符合FCM的格式要求。比如priority要设置在根级别,并且值为"high"(确保通知能快速送达)。
4. 可选:改用data消息模式(更灵活)
如果用notification消息,FCM会自动处理展示和缓存,但合并规则由FCM控制;如果改用data消息,所有的通知展示逻辑由你的Android客户端代码处理,你可以自己控制离线消息的缓存和展示,避免FCM的自动合并。不过这需要你在客户端实现FirebaseMessagingService来处理data消息。
示例data消息payload:
{ "GCM": "{ \"data\": { \"text\": \"test\", \"title\": \"Titre\", \"custom_key\": \"custom_value\" }, \"priority\": \"high\", \"time_to_live\": 3600 }" }
三、测试验证
修改后,你可以按以下步骤测试:
- 打开飞行模式,发送3条不同
collapse_key的通知 - 关闭飞行模式,检查是否能收到所有3条通知
- 同时可以在FCM控制台的消息记录里查看每条消息的状态,确认是否都被正确缓存和送达
内容的提问来源于stack exchange,提问作者Parwanas
相关产品推荐
相关产品推荐

