Flutter中FCM后台推送通知在Android通知栏重复显示求助
解决Flutter FCM后台通知重复显示问题
问题根源
- 系统自动通知+本地通知重复触发:当FCM请求包含
notification字段时,Android应用处于后台状态下,系统会自动弹出这条通知;同时你的_firebaseMessagingBackgroundHandler又调用flutter_local_notifications再次显示本地通知,导致两条重复通知。 - 重复注册后台消息处理器:在
main()和initState()中重复调用FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler),可能引发回调多次执行。
解决方案
1. 调整FCM消息结构(核心修复)
移除请求中的notification字段,仅保留data字段,完全通过本地通知控制显示逻辑。修改后的请求JSON:
{ "priority": "high", "data": { "type": "notification", "click_action": "FLUTTER_NOTIFICATION_CLICK", "screen": "notification_screen", "id": "1", "title": "background", "body": "background test 123123" }, "to": "MY_DEVICE_TOKEN" }
若必须保留
notification字段,需在_firebaseMessagingBackgroundHandler中跳过本地通知显示,仅处理data逻辑,但不推荐这种方式——系统通知和本地通知的样式、行为难以统一。
2. 移除重复的后台处理器注册
删除_WeatherAppState的initState()中的FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler),该注册仅需在main()中执行一次:
class _WeatherAppState extends State<WeatherApp> { @override void initState() { super.initState(); FirebaseMessaging.onMessage.listen(showFlutterNotification); // 移除下面这行重复注册 // FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); FirebaseMessaging.onMessageOpenedApp.listen(handleMessage); FirebaseMessaging.instance.getInitialMessage().then(handleMessage); } // ... 其他代码不变 }
3. 优化本地通知ID(可选)
将showFlutterNotification中的固定ID0改为动态值,避免后续通知被覆盖,同时确保每条通知唯一:
void showFlutterNotification(RemoteMessage message) { // 用messageId或时间戳作为唯一ID final notificationId = message.messageId?.hashCode ?? DateTime.now().millisecondsSinceEpoch; // 从data字段获取标题和内容(因为已移除notification字段) final title = message.data["title"]; final body = message.data["body"]; if (title != null && body != null) { flutterLocalNotificationsPlugin.show( notificationId, title, body, NotificationDetails( android: AndroidNotificationDetails( channel.id, channel.name, channelDescription: channel.description, icon: "@mipmap/ic_launcher", // 建议设置正确图标,不要留空 ), ), payload: message.data["screen"], ); } }
4. 确认后台handler初始化逻辑
setupFlutterNotifications中的isFlutterLocalNotificationsInitialized判断已能避免重复初始化,无需修改,但需确保Firebase.initializeApp在后台handler中正确执行:
@pragma('vm:entry-point') Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); await setupFlutterNotifications(); showFlutterNotification(message); }
验证步骤
- 重新打包安装应用到Android设备
- 将应用退到后台(不要杀死进程)
- 发送修改后的FCM请求
- 检查通知栏是否只显示一条通知
内容的提问来源于stack exchange,提问作者dumibell
相关产品推荐
相关产品推荐

