Flutter中FCM后台通知重复显示问题求助
解决FCM后台接收时显示两条通知的问题
核心原因
当FCM发送包含notification字段的通知类型消息时,Android系统会在应用后台/进程杀死状态下自动展示原生通知;同时你的自定义MonServiceMessagingFirebase服务又会触发自定义通知逻辑,最终导致两条通知重复出现。
分步解决方案
1. 切换为纯数据消息格式
修改FCM发送端的消息结构,去掉notification字段,仅保留data字段。这样系统不会自动生成原生通知,所有消息都会交由你的自定义逻辑处理。
示例发送payload:
{ "to": "目标设备令牌", "data": { "title": "自定义通知标题", "body": "自定义通知内容", "click_action": "FLUTTER_NOTIFICATION_CLICK", // 按需添加其他自定义业务字段 } }
2. 配置Flutter后台消息处理器
在Flutter层注册后台消息处理回调,确保后台收到数据消息时触发自定义通知:
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter/material.dart'; import 'dart:convert'; // 后台消息处理回调 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 配置Android通知渠道(需与前台通知渠道一致) const AndroidNotificationDetails androidChannel = AndroidNotificationDetails( 'custom_notification_channel', // 自定义渠道ID '自定义通知渠道', channelDescription: '用于展示FCM自定义通知', importance: Importance.max, priority: Priority.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidChannel); // 展示自定义通知 await flutterLocalNotificationsPlugin.show( DateTime.now().millisecondsSinceEpoch % 10000, // 唯一ID避免重复覆盖 message.data['title'], message.data['body'], notificationDetails, payload: jsonEncode(message.data), ); } void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 注册后台消息处理器 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); // 初始化flutter_local_notifications(前台通知也依赖此初始化) const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); await FlutterLocalNotificationsPlugin().initialize(initSettings); runApp(const MyApp()); }
3. 修正AndroidManifest配置
- 移除
AndroidManifest.xml中默认的FirebaseMessagingService声明(如果存在); - 确保自定义
MonServiceMessagingFirebase服务配置正确,适配Android 12+的权限要求:
<service android:name=".MonServiceMessagingFirebase" android:exported="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
- 检查自定义服务代码,确保没有重复发送通知的逻辑(所有通知展示统一由Flutter层的前台/后台处理器完成)。
4. 统一前台通知逻辑
前台接收消息时,通过FirebaseMessaging.onMessage监听并使用相同的flutter_local_notifications逻辑展示通知,保持前后台通知样式一致:
FirebaseMessaging.onMessage.listen((RemoteMessage message) { final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const AndroidNotificationDetails androidChannel = AndroidNotificationDetails( 'custom_notification_channel', '自定义通知渠道', channelDescription: '用于展示FCM自定义通知', importance: Importance.max, priority: Priority.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidChannel); flutterLocalNotificationsPlugin.show( DateTime.now().millisecondsSinceEpoch % 10000, message.data['title'], message.data['body'], notificationDetails, payload: jsonEncode(message.data), ); });
关键注意事项
- 若业务必须使用
notification字段的消息,可在发送时添加click_action: "FLUTTER_NOTIFICATION_CLICK"并在AndroidManifest中配置对应Activity的intent-filter,但这种方式仍可能触发系统原生通知,优先推荐纯数据消息方案; - 测试时需覆盖应用前台、后台、进程杀死三种状态,确保所有场景下仅展示一条自定义通知;
- 确保
flutter_local_notifications初始化时使用的图标资源存在,避免通知图标异常。
内容的提问来源于stack exchange,提问作者pierre pontfort
相关产品推荐
相关产品推荐

