You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中FCM后台推送通知在Android通知栏重复显示求助

解决Flutter FCM后台通知重复显示问题

问题根源

  1. 系统自动通知+本地通知重复触发:当FCM请求包含notification字段时,Android应用处于后台状态下,系统会自动弹出这条通知;同时你的_firebaseMessagingBackgroundHandler又调用flutter_local_notifications再次显示本地通知,导致两条重复通知。
  2. 重复注册后台消息处理器:在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);
}

验证步骤

  1. 重新打包安装应用到Android设备
  2. 将应用退到后台(不要杀死进程)
  3. 发送修改后的FCM请求
  4. 检查通知栏是否只显示一条通知

内容的提问来源于stack exchange,提问作者dumibell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:35:57