Flutter iOS端FCM在应用终止时无法处理消息的问题
iOS端Firebase Messaging应用终止后无法处理通知数据的解决办法
问题总结
用Flutter开发的App,通过Firebase Messaging向订阅主题的用户推送通知,通知携带的数据需存入SharedPreferences。多数场景功能正常,但iOS端App被彻底杀死后:
onBackgroundMessage()完全不触发(通知能正常显示,但数据无法存储)getInitialMessage()也未生效
仅当第一条通知唤醒App后,第二条通知才能正常触发数据处理逻辑。
具体修复步骤
1. 修正getInitialMessage()的调用逻辑
你main()函数里的写法存在错误,仅返回了函数引用,并未实际调用处理逻辑。正确写法如下:
await messaging.getInitialMessage().then((RemoteMessage? message) { if (message != null) { firebaseMessagingBackgroundHandler(message); } });
必须判断message不为空——只有用户点击通知启动App时,该方法才会返回消息对象;若用户未点击通知或为静默推送,getInitialMessage()会返回null。
2. 确保推送Payload符合iOS后台处理要求
iOS对终止状态下的推送有严格限制,Payload必须包含以下字段:
content-available: 1:告知系统可唤醒App进行后台处理mutable-content: 1:允许修改通知内容(建议添加以保障数据处理权限)
示例Payload结构:
{ "notification": { "title": "新消息", "body": "XX发来一条消息" }, "data": { "sender": "XX", "content": "测试内容" }, "apns": { "payload": { "aps": { "content-available": 1, "mutable-content": 1 } } }, "topic": "你的主题名称" }
若通过Firebase控制台发送,需在高级选项的APNs设置中勾选"Content available"和"Mutable content"。
3. 二次验证iOS后台模式配置
虽然你提到已启用后台权限,仍需确认以下配置:
Info.plist中需包含:
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array>
- Xcode的Signing & Capabilities → Background Modes中,必须勾选"Remote notifications"
4. 遵守onBackgroundMessage()的执行限制
iOS终止状态下,该回调有严格约束:
- 必须为顶层函数(不能是类的方法),且需添加
@pragma('vm:entry-point')注解(此点你已正确配置) - 不可使用Flutter UI相关API,仅能执行数据存储等后台操作(你的代码仅调用SharedPreferences,符合要求)
- 执行时长不得超过30秒,否则会被系统强制终止
5. 测试时的注意事项
- 必须使用真实设备,模拟器不支持终止状态下的推送唤醒功能
- 务必测试Release版本,Debug版本存在调试限制,测试结果不准确
- 测试时需先断开Xcode与设备的连接,手动杀死App后再发送推送
6. 检查插件版本兼容性
确保firebase_messaging和shared_preferences使用最新稳定版本,旧版本可能存在iOS终止状态下的兼容问题。
额外优化建议
- 可在
getInitialMessage()的处理逻辑中添加本地日志(如写入文件),便于排查该方法是否被调用 - 若用户未点击通知,
getInitialMessage()不会触发,此类场景只能依赖onBackgroundMessage(),而它能否触发完全取决于Payload中content-available:1的配置
内容的提问来源于stack exchange,提问作者Mastah
相关产品推荐
相关产品推荐

