Flutter中Firebase Messaging后台自定义通知UI重复显示问题求助
解决Flutter Firebase Messaging后台双通知问题
核心原因
你收到双通知是因为从Firebase控制台发送的是通知类型消息(Notification Payload),这类消息会被Firebase SDK自动触发默认通知,同时你自己又用flutter_local_notifications发了自定义通知,直接导致重复显示。
解决步骤
1. 发送纯数据类型消息
从Firebase控制台发消息时,别用默认的「通知」标签页,切换到「自定义数据」(Data)标签,手动填写title、body等你需要的字段。这样Firebase不会自动显示通知,完全由你的代码控制展示逻辑。
如果必须用混合消息(同时带notification和data字段),只有APP在前台时能拦截默认通知,后台仍会被Firebase自动展示,所以优先推荐纯数据消息。
2. 正确配置后台消息回调
FirebaseMessaging.onBackgroundMessage的回调必须是顶级函数(不能是类的方法,也不能依赖Flutter上下文),而且要在回调里重新初始化flutter_local_notifications——因为后台隔离环境和前台运行环境是完全分开的。
示例代码:
// 顶级后台消息处理函数,必须写在类外部 Future<void> _firebaseBackgroundMessageHandler(RemoteMessage message) async { // 先初始化Firebase await Firebase.initializeApp(); // 初始化flutter_local_notifications插件 const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); final FlutterLocalNotificationsPlugin notificationsPlugin = FlutterLocalNotificationsPlugin(); await notificationsPlugin.initialize(initSettings); // 配置自定义通知的渠道和操作按钮 const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'custom_notification_channel', // 唯一渠道ID '自定义通知渠道', // 渠道名称 channelDescription: '带操作按钮的自定义通知渠道', importance: Importance.high, priority: Priority.high, // 添加需要的操作按钮 actions: [ AndroidNotificationAction('action_confirm', '确认'), AndroidNotificationAction('action_cancel', '取消'), ], ); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); // 显示自定义通知,从data字段中取标题和内容 await notificationsPlugin.show( message.messageId.hashCode, // 唯一通知ID message.data['title'], message.data['body'], notificationDetails, payload: message.data['payload'], // 传递额外数据,用于点击按钮时处理逻辑 ); } // 在main函数里注册后台回调 void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 注册后台消息处理逻辑 FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundMessageHandler); runApp(MyApp()); }
3. 额外注意事项
- 后台回调里绝对不能使用Flutter上下文(比如
Navigator跳转),只能做本地通知、原生插件调用或网络请求这类无上下文依赖的操作。 - Android 8.0+必须配置通知渠道,否则自定义通知可能无法正常显示,上面代码已包含渠道配置,确保渠道ID唯一即可。
- 检查
AndroidManifest.xml,不要添加FirebaseMessaging相关的默认通知过滤器,避免干扰自定义通知逻辑。
内容的提问来源于stack exchange,提问作者Ahmed Hallaq
相关产品推荐
相关产品推荐

