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

Flutter iOS端Firebase重复通知问题求助:应用前台收两条重复通知

iOS前台收重复FCM通知+数据重复的解决办法

为啥会这样?

  1. 两条通知的问题:你发的FCM消息是「混合消息」——既带了data自定义字段,又在APNS的aps.alert里写了通知内容。iOS前台时,FCM会把data部分推给Flutter应用的onMessage回调,同时iOS系统还会自动根据aps.alert弹一条系统通知,两条就重复了。后台时系统统一处理aps.alert,所以只显示一条。
  2. 数据重复的问题:你在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:20:05