Flutter Firebase Messaging iOS重启后无法接收纯数据消息
iOS 对纯数据(静默)推送有严格的系统级限制,加上你的代码配置和推送Payload存在几个明确问题,才会出现重启后无法接收消息的现象,按以下步骤修复即可:
1. 修正推送请求的APNs配置
你当前的APNs配置缺少必填头信息,且参数值错误,会导致iOS重启后直接丢弃推送:
- 纯静默推送(
content-available:1)必须声明apns-push-type为background,否则APNs不会按后台唤醒消息投递 - 静默推送的优先级必须设为
5,设为高优先级10会被APNs限流甚至拒绝投递 sound字段值错误,系统识别的默认提示音值为default,写enable无效- 建议显式声明
apns-topic为你应用的Bundle ID,避免证书匹配失败
修正后的APNs配置如下:
"apns": { "headers": { "apns-push-type": "background", "apns-priority": "5", "apns-topic": "替换为你的应用Bundle ID" }, "payload": { "aps": { "category": "OPEN_CHAT_ROOM", "sound": "default", "content-available": 1 } } }
注意:iOS对静默推送有硬性限流规则,单应用每小时最多接收2~3条静默推送,超出部分会被系统直接丢弃,该限制无法绕过。
2. 调整插件初始化顺序
你当前的代码中,AwesomeNotifications是在Firebase初始化流程的末尾才初始化的,iOS重启后收到静默推送会直接唤醒应用执行全局的_firebaseMessagingBackgroundHandler,此时通知插件还未完成初始化,调用展示通知的逻辑会直接失败。
把通知插件的初始化提前到main.dart的最开头,保证任何场景下插件都可用:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 提前初始化AwesomeNotifications,保证后台/冷启动/重启唤醒场景可用 await AwesomeNotifications().initialize('resource://drawable/logo', [ NotificationChannel( channelGroupKey: 'basic_tests', channelKey: 'basic_channel', channelName: 'Basic notifications', channelDescription: 'Notification channel for basic tests', defaultColor: Color(0xFF9D50DD), ledColor: Colors.white, importance: NotificationImportance.High), ]); NotificationController _notificationController = NotificationController(); //Initialize firebase await Firebase.initializeApp(); await _notificationController.startNotificationService(); // 主动获取一次FCM token,避免重启后token未刷新导致推送失败 String? token = await FirebaseMessaging.instance.getToken(); debugPrint("Current FCM token: $token"); //Listen for the Token change FirebaseMessaging.instance.onTokenRefresh.listen((String token) { print("New token: $token"); // 记得把新token同步到你的服务端 }); //Apply MultiProvider runApp(MultiProvider( providers: [ //provider lists ], child: MyApp(), )); }
修改完成后,删除initializFirebaseeNotifications方法中调用initializeAwesomeNotifications()的代码,避免重复初始化。
3. 检查Xcode必要配置
缺少系统权限配置也会导致静默推送无法唤醒应用:
- 打开项目的
Signing & Capabilities页,添加Background Modes能力,勾选Remote notifications选项 - 确认
Info.plist中UIBackgroundModes数组包含remote-notification值 - 不要关闭Firebase Messaging的自动初始化功能(
autoInitEnabled默认保持true即可),否则重启后FCM无法自动完成token注册
4. 系统限制说明
以下场景属于iOS系统级安全/省电策略,代码层面无法绕过:
- 设备重启后,用户未首次解锁设备前,所有第三方应用的静默推送都会被系统拦截,必须解锁一次后才能正常接收
- 用户手动上滑杀掉应用后,静默推送的投递率会大幅降低,无法保证必达
如果需要更高的推送到达率,建议放弃纯data-only方案,改用带notification字段+mutable-content:1的通知,通过iOS Notification Service Extension在通知展示前拦截修改内容,用AwesomeNotifications自定义展示样式,既不会出现重复通知,也能保证重启后、杀应用后的通知到达率。
内容的提问来源于stack exchange,提问作者PeakGen

