Flutter使用FCM推送时iOS端桌面应用图标通知角标不显示
问题背景
- 基于Firebase Cloud Messaging实现主题订阅推送功能:Android端全功能运行正常,iOS端在前台、后台、应用终止状态(profile模式)下均可在通知中心正常收到推送
- 异常现象:iOS桌面应用图标始终不显示通知角标
- 已尝试操作:在搭载iOS 15系统的iPhone 12 Pro、iPhone Xs设备上,分别使用debug、profile模式测试;集成flutter_app_badger插件后仍无法正常显示角标计数
现有实现代码
入口文件main.dart代码
Future<void> _messageHandler(RemoteMessage message) async { print('background message ${message.notification!.body}'); } Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ).then((value) { FirebaseMessaging.onBackgroundMessage(_messageHandler); }); runApp(MyApp()); }
首屏initState逻辑代码
@override void initState() { super.initState(); PushNotify().init(context); messaging = FirebaseMessaging.instance; messaging.subscribeToTopic("messaging"); messaging.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); if (Platform.isIOS) { messaging.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true, ); } FirebaseMessaging.onMessage.listen((RemoteMessage event) { // FlutterAppBadger.updateBadgeCount(1); if (event.notification != null) { print('Message also contained a notification: ${event.notification}'); } }); FirebaseMessaging.onMessageOpenedApp.listen((message) { print('Message clicked!'); // FlutterAppBadger.removeBadge(); }); }
排查方向与修复方案
优先验证角标能力本身是否正常
先在initState里延迟2秒执行FlutterAppBadger.updateBadgeCount(3),如果执行后桌面图标能正常显示角标,说明客户端权限、原生配置均无问题,故障点在推送 payload 层面;如果手动调用仍无法显示角标,再往下排查客户端配置问题。修复推送payload缺失badge字段问题(最高发原因)
iOS系统更新角标强依赖推送payload中
aps节点下的badge字段,没有该字段时无论客户端如何配置,都不会自动更新角标。- 若通过Firebase控制台发送测试推送,需要进入高级选项的iOS配置栏,手动填写角标数值,默认配置不会自动携带badge参数
- 若通过服务端接口发送推送,必须在payload中补充badge字段,示例结构:
{ "message": { "topic": "messaging", "notification": { "title": "推送标题", "body": "推送内容" }, "aps": { "alert": "推送内容", "badge": 1, "sound": "default" } } }修复权限请求时序问题
现有代码未等待iOS权限请求完成就配置前台展示选项,且权限请求逻辑位置靠后,会导致配置不生效,修正后的逻辑参考:@override void initState() async { super.initState(); PushNotify().init(context); messaging = FirebaseMessaging.instance; await messaging.subscribeToTopic("messaging"); if (Platform.isIOS) { // 先请求权限,await等待用户授权结果 NotificationSettings settings = await messaging.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true, ); // 可打印日志确认badge权限实际状态 print('badge权限状态: ${settings.badgeSetting}'); // 仅在授权成功后配置前台展示选项 if (settings.authorizationStatus == AuthorizationStatus.authorized) { messaging.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); } } else { messaging.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); } FirebaseMessaging.onMessage.listen((RemoteMessage event) { // 前台收到推送需要自定义角标数值时再开启 // FlutterAppBadger.updateBadgeCount(1); if (event.notification != null) { print('Message also contained a notification: ${event.notification}'); } }); FirebaseMessaging.onMessageOpenedApp.listen((message) { print('Message clicked!'); // 用户点击通知进入应用时按需清除角标 // FlutterAppBadger.removeBadge(); }); }检查系统级与项目配置
- 打开iOS系统设置,找到对应应用的通知设置页,确认「标记」(角标)开关处于开启状态;测试时暂时关闭专注模式、定时摘要功能,排除系统策略拦截
- 打开iOS项目的
Info.plist文件,确认不存在将UIApplicationBadgeNumber设为0的配置项 - 在Xcode中打开项目,确认Signing & Capabilities页已添加Push Notifications能力,Background Modes中已勾选Remote notifications选项
- 若使用flutter_app_badger,需在
Info.plist的LSApplicationQueriesSchemes数组中添加badger项
内容的提问来源于stack exchange,提问作者Zahra
相关产品推荐
相关产品推荐

