Flutter iOS端Firebase重复通知问题求助:应用前台收两条重复通知
iOS前台收重复FCM通知+数据重复的解决办法
为啥会这样?
- 两条通知的问题:你发的FCM消息是「混合消息」——既带了
data自定义字段,又在APNS的aps.alert里写了通知内容。iOS前台时,FCM会把data部分推给Flutter应用的onMessage回调,同时iOS系统还会自动根据aps.alert弹一条系统通知,两条就重复了。后台时系统统一处理aps.alert,所以只显示一条。 - 数据重复的问题:你在
data和aps.alert里都写了sohbetId、aliciId这些自定义字段,解析的时候自然会拿到两份一样的数据,显示就重复了。
怎么解决?
1. 调整FCM消息结构
把自定义字段统一放到data中,aps.alert只保留必要的系统通知配置(比如sound),或者干脆删掉aps.alert,让Flutter用本地通知自主展示,避免系统自动弹窗。修改后的JSON示例:
{ "message": { "token": "...", "data": { "body": "value1", "title": "value2", "sohbetId": "1", "aliciId": "xxx" }, "android": { "priority": "high" }, "apns": { "headers": { "apns-priority": "10" }, "payload": { "aps": { "sound": "default" // 若需后台系统弹窗,可保留aps.alert,但不要放自定义字段,title/body与data保持一致 } } } } }
2. Flutter端统一通知处理逻辑
用flutter_local_notifications插件自主展示通知,不再依赖系统自动弹窗。监听onMessage回调,收到消息后直接调用本地通知接口,确保前台只弹一次。代码片段示例:
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'dart:convert'; final FlutterLocalNotificationsPlugin _localNotify = FlutterLocalNotificationsPlugin(); void setupFCM() async { FirebaseMessaging messaging = FirebaseMessaging.instance; // iOS必须请求通知权限 await messaging.requestPermission( alert: true, badge: true, sound: true, ); // 初始化本地通知配置 const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const iosInit = DarwinInitializationSettings(); await _localNotify.initialize(const InitializationSettings(android: androidInit, iOS: iosInit)); // 前台收到消息时,触发自定义本地通知 FirebaseMessaging.onMessage.listen((message) { final data = message.data; final title = data['title'] ?? ''; final body = data['body'] ?? ''; _showLocalNotify(title, body, jsonEncode(data)); }); } void _showLocalNotify(String title, String body, String payload) async { const androidDetails = AndroidNotificationDetails( 'chat_channel', // 自定义渠道ID '聊天通知', // 自定义渠道名称 importance: Importance.max, priority: Priority.high, ); const iosDetails = DarwinNotificationDetails(); await _localNotify.show( DateTime.now().microsecond, // 用时间戳做通知ID,避免重复覆盖 title, body, const NotificationDetails(android: androidDetails, iOS: iosDetails), payload: payload, ); }
3. 移除重复的自定义字段
删掉aps.alert里的sohbetId、aliciId等自定义字段,所有业务字段只保留在data中,解析时直接从message.data获取即可,避免数据重复。
额外提醒
- iOS后台时,点击系统通知后,可通过
FirebaseMessaging.instance.getInitialMessage()或FirebaseMessaging.onMessageOpenedApp.listen()获取data内容。 - 确保
firebase_messaging和flutter_local_notifications插件为最新版本,规避旧版本兼容性问题。
内容的提问来源于stack exchange,提问作者twice_flutter
相关产品推荐
相关产品推荐

