我把91网的通知干扰拆给你看:其实一点都不玄学(这点太容易忽略)
我把 91 网的通知干扰拆给你看:其实一点都不玄学(这点太容易忽略)

很多人接到“通知推送不准”“有的通知被吞了”“通知被打包成一条”这类反馈,就立刻把原因往神秘或平台黑箱里推。真相通常比想象简单:推送体系由服务器、网络、平台 SDK、浏览器/系统、以及用户设置多层共同作用,一处小配置不当就会造成“干扰”。下面把常见原因、排查步骤和可落地的修复方法拆开说清楚,最后强调一个最容易被忽视但常常决定体验的细节。
一、通知干扰到底长什么样(常见症状)
- 通知延迟很严重,或只在一段时间内到达
- 多条通知被合并为一条或覆盖掉(只能看到最新一条)
- 有些设备/浏览器能收到,有些完全收不到
- 通知内容缺失(没有标题/图标/行为)或只显示“静默”推送
- 用户反映“我已经允许通知,但没弹窗/没声音”
二、构成推送链路的关键环节(简单理解会降低排查成本)
- 服务器端:推送消息的生成、优先级、TTL、collapse key/tag 等
- 推送网关:FCM、APNs、Web Push 服务的处理与速率限制
- 设备/浏览器:操作系统的通知渠道、Doze/省电策略、浏览器 Service Worker
- 用户端设置:系统通知权限、应用级静音、勿扰模式、渠道等级
- 网络与代理:移动网络切换、CDN 缓存、VPN 或拦截代理的影响
三、逐步排查流程(带你从“可见”到“不可见”定位) 1) 重现问题并归类
- 先在有问题的设备上复现:记录时间、网络类型、App 是否在前台/后台、是否锁屏。
- 看是“延迟”还是“丢失”还是“被合并”。这能迅速缩小范围。
2) 服务器日志与推送网关返回值
- 检查推送网关(FCM/APNs/Web Push)的返回:是否报错、是否被限流、message_id/response code。
- 记录发送时间、payload、目标 token、ttl、priority 等字段。
3) 验证 payload 与优先级配置
- FCM:priority(high/normal),ttl(秒),collapse_key,notification vs data payload 的混用。
- APNs:apns-priority(10/5),apns-expiration,collapse-id。
- Web Push:TTL、Urgency 头(high/normal/low),payload 是否加密。
4) 客户端日志与 Service Worker 调试(网页/Hybrid)
- Chrome DevTools -> Application -> Service Workers:看 push 事件是否触发,event.data。
- 在 Android/iOS 上查看系统日志(adb logcat、Console)判断是否被系统吞掉或被其他策略阻止。
5) 检查系统/浏览器通知通道与用户设置
- Android 8+ 的 Notification Channel:channel 的 importance 决定是否有声音/震动/弹出。
- 如果 channel 被用户改成低优先级,所有基于该 channel 的推送都会“静默”。
- iOS 的用户通知权限和 Focus 模式(勿扰)也会影响展示。
6) 网络与电源策略
- Android Doze 或厂商的省电策略(华为、OPPO、小米)会限制后台网络和推送心跳,导致延迟或丢失。
- 测试在 Wi‑Fi 与移动网络、锁屏与解锁、节电模式开/关 情况下的行为差别。
四、常见问题与对应修复方法(按症状给出落地操作)
问题:通知被合并或覆盖(只能看到最新一条)
- 原因:使用了相同的 collapse_key / collapse-id / notification tag,或 Android 的 notificationId 相同导致覆盖。
- 修复:为需要独立展示的通知使用不同的 tag/notificationId;只对真正要合并的场景使用 collapse key。
问题:通知沉寂(没有声音/不弹出/仅静默)
- 原因:Android 通知通道 importance 过低;payload 使用了 data-only 导致仅触发静默;apns-priority/FCM priority 设置不当。
- 修复:确认 channel 的 importance 设置为高(例如 IMPORTANCE_HIGH);服务器发送需要前台展示的部分时使用含 notification 的 payload 或设置合适的优先级(FCM priority=high,APNs apns-priority=10)。
问题:延迟/丢失(尤其在锁屏或深度省电下)
- 原因:Doze/厂商省电策略限制后台网络;TTL 太短或优先级被降低导致被网关丢弃;心跳(persistent connection)被断。
- 修复:优化心跳/重连策略,针对重要消息用高优先级并适当提高 TTL;在 app 内提示用户关闭系统级的电池优化(或在首次引导中说明)。
问题:只有某些设备/浏览器能收到
- 原因:token/device 注册生命周期问题、老版本 SDK、浏览器不支持某些头部或加密机制。
- 修复:确保 token/registration 在设备端及时刷新并同步到服务器;升级 SDK;用平台工具逐台调试。
五、实用调试工具与命令
- Chrome DevTools:Application -> Service Workers / Push -> 查看 push 事件。
- curl 调试 Web Push(示例省略,可根据需要提供)。
- Firebase Console / FCM Diagnostics:在线发送测试消息、查看响应。
- adb logcat(Android)与 macOS Console(连接 iOS 设备)查看系统日志。
- Wireshark/tcpdump:抓包排查 TLS 链接与请求是否到达。
- 服务器端日志 + 增加请求/响应追踪 ID:便于回溯某条消息的生命周期。
六、代码片段示例(帮助你理解关键字段)
-
FCM(HTTP v1)片段(示例要点:设置 priority 与 ttl) { "message": { "token": "", "android": { "priority": "high", "ttl": "3600s", "notification": { "title": "你有一条新消息", "body": "点击查看详情" } }, "apns": { "headers": { "apns-priority": "10", "apns-expiration": "0" }, "payload": { "aps": { "alert": { "title": "你有一条新消息", "body": "点击查看详情" } } } } } }
-
Web Push(HTTP 头要点) TTL: 3600 Urgency: high
七、那一条最容易被忽略?——通知渠道(Notification Channel / Importance) 很多工程师把注意力放在服务器的推送逻辑、优先级与 TTL 上,但忽略了 Android 8+ 的 Notification Channel。创建 channel 时,如果使用了默认或测试时的低 importance,一旦用户(或者某些厂商 ROM 的系统设置)把 channel 调为静音,后续所有通过该 channel 发出的通知都会被“降级”为无声且可能不弹出,无论你服务器如何设置 priority,都无法突破系统对 channel 的控制。
导致的常见误区:
- 在应用第一次启动就固定创建 channel,之后更新通知逻辑却不检查或更新 channel 级别。
- 把唤醒类、重要告警类混用同一 channel,用户仅对某一类感到烦就会把整个 channel 静音,结果所有重要通知都没了。
- 认为“用户已经允许通知”就万事大吉,忽视了 channel 的粒度设置与用户逐-channel 的控制。
解决策略(实操)
- 按通知类型拆 channel:例如“交易类”“账号安全”“营销/活动”,把重要的放在高重要性的 channel。
- 在应用内提供“通知设置”入口,显示每个 channel 的说明并引导用户如何打开(深度链接到系统设置页)。
- 在版本更新中检查并必要时迁移旧 channel:如果原先 channel importance 太低,可在升级说明中解释并引导用户手动开启;对于新用户,用合适的初始 importance 创建 channel。
八、实际工作中的检查清单(发布前后都能用)
- [ ] 各平台的优先级/priority 是否对应平台规范?(FCM/APNs/Web Push)
- [ ] 是否合理使用 collapse_key/tag/notificationId?会不会误覆盖?
- [ ] Android 是否按通知类型创建不同 channel?channel importance 是否合理?
- [ ] payload 中是否同时维护 notification 与 data 的兼容逻辑(特别是 iOS vs Android 的差异)?
- [ ] 是否考虑厂商省电策略、Doze、心跳重连机制?
- [ ] 是否对 token 生命周期、重试与限流有监控?
- [ ] 是否在产品侧提供用户可见的“通知设置”入口并引导用户?
结语 通知体验不是单点问题,而是一个链路问题:一个小配置(像 channel importance、collapse-key、ttl)就能决定数百万用户的感知差异。把每个环节的参数当成影响因子去验证,形成系统化的监控与回溯流程,你会发现所谓“通知干扰”很多时候并不玄学,只是被忽略了细节。