如何在iOS上禁用FCM前台通知弹窗?
我遇到一个问题:iOS设备上应用处于前台时,FCM总会推送通知,这与Android不同——Android仅在应用后台或终止状态下才推送通知,我希望iOS实现相同的行为。
我尝试使用setForegroundNotificationPresentationOptions方法但未生效:
await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: false, badge: false, sound: true, );
查阅FCM文档发现:
默认情况下,苹果设备仅在应用后台或终止时显示通知消息。调用此方法可自定义应用前台时的通知展示行为。
重要提示:请求的权限和用户设置优先于此配置。
这说明问题可能出在FCM权限请求上,但我不能将alert设为false,因为这会同时阻止前台和后台的通知弹窗:
static Future<bool> askForNotificationPermission() async { final settings = await FirebaseMessaging.instance.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized) { return true; } return false; }
另外我搜索发现问题可能与使用的awesome_notifications包有关,它可能干扰默认行为。如何仅针对前台设置参数并覆盖权限请求时的配置?
补充说明:
我实际并没有用Firebase申请权限,而是用awesome_notifications,代码如下:
static Future<void> initializeNotificationsService() async { await AwesomeNotifications().initialize( null, [ NotificationChannel( channelGroupKey: "high_importance", channelKey: "high_importance", channelName: 'Notifications', channelDescription: 'Notification channel for alerting users about their scedules, chat messages and so on', defaultColor: AppColors.primaryColor, importance: NotificationImportance.Max, playSound: true, channelShowBadge: true, ), ], channelGroups: [ NotificationChannelGroup( channelGroupKey: "schedule_group_key", channelGroupName: 'Schedule'), NotificationChannelGroup( channelGroupKey: "chat_group_key", channelGroupName: 'Conversations'), ], ); await AwesomeNotifications() .isNotificationAllowed() .then((isAllowed) async { if (!isAllowed) { await AwesomeNotifications().requestPermissionToSendNotifications(); } }); await AwesomeNotifications().setListeners( onActionReceivedMethod: onActionReceivedMethod, onDismissActionReceivedMethod: onDismissActionReceivedMethod, onNotificationCreatedMethod: onNotificationCreatedMethod, onNotificationDisplayedMethod: onNotificationDisplayedMethod, ); }
解决方案
拦截FCM前台通知,手动控制展示时机
监听FCM的前台消息回调,判断应用状态,仅在后台/终止时触发通知展示:FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) { // 前台时不展示通知,可按需更新本地状态或做静默处理 return; } else { // 后台/终止时调用AwesomeNotifications创建通知 AwesomeNotifications().createNotification( content: NotificationContent( id: DateTime.now().millisecondsSinceEpoch % 10000, channelKey: "high_importance", title: message.notification?.title ?? '', body: message.notification?.body ?? '', ), ); } });禁用AwesomeNotifications自动处理FCM通知
如果使用了awesome_notifications_fcm插件,初始化时关闭自动弹窗,完全手动控制:await AwesomeNotificationsFcm().initialize( onFcmTokenHandle: (token) {}, onFcmSilentDataHandle: (data) {}, onNativeTokenHandle: (token) {}, enableFcmPopups: false, // 禁用自动展示FCM通知 );确保FCM前台展示配置生效
在权限申请完成后调用setForegroundNotificationPresentationOptions,覆盖默认行为:// 权限申请完成后执行 await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: false, badge: false, sound: false, );检查AwesomeNotifications监听回调
在通知创建/展示的回调中判断应用状态,避免前台强制展示:static Future<void> onNotificationCreatedMethod(ReceivedNotification receivedNotification) async { if (WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) { // 仅后台时处理通知展示逻辑 } }
内容的提问来源于stack exchange,提问作者MOM 74

