Flutter Android端FCM后台通知如何按标题过滤显示?
解决FCM后台通知仅特定标题才显示的问题
问题根源
Android平台下,当App处于后台时,FCM的纯通知类型消息(仅包含notification字段)会被系统直接拦截并显示通知,不会触发你写的firebaseMessagingBackgroundHandler中的判断逻辑。只有当消息是数据类型消息(仅data字段)或通知+数据混合消息时,后台handler才会被触发,这时你才能自定义通知显示逻辑。
另外你当前的后台代码存在明显问题:只创建了通知渠道,没有调用show方法触发通知显示,这也是逻辑失效的核心原因之一。
解决方案
1. 调整FCM消息发送格式
发送消息时,改用数据消息或者混合消息,示例格式如下(以FCM API POST请求为例):
// 数据消息(完全由自定义逻辑处理) { "to": "你的设备令牌", "data": { "title": "attendance", "body": "考勤通知内容", "click_action": "FLUTTER_NOTIFICATION_CLICK" } }
或者混合消息(兼顾系统默认通知处理和自定义逻辑):
{ "to": "你的设备令牌", "notification": { "title": "attendance", "body": "考勤通知内容" }, "data": { "title": "attendance", "body": "考勤通知内容" } }
2. 修改后台消息处理代码
更新firebaseMessagingBackgroundHandler,确保在符合条件时手动调用本地通知插件显示通知,同时完成必要的初始化:
// 必须是全局顶级函数,不能放在类内部 Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { // 初始化Firebase(后台环境需确保Firebase已初始化) await Firebase.initializeApp(); // 初始化本地通知插件 final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid); await flutterLocalNotificationsPlugin.initialize(initializationSettings); // 创建通知渠道(只需执行一次,可提前初始化) const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', 'high_importance_notification', importance: Importance.max, ); await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); // 获取标题:优先从data字段取,兼容数据/混合消息格式 String? title = message.data['title'] ?? message.notification?.title; // 仅当标题为attendance时显示通知 if (title == "attendance") { String? body = message.data['body'] ?? message.notification?.body; await flutterLocalNotificationsPlugin.show( message.hashCode, title, body, const NotificationDetails( android: AndroidNotificationDetails( 'high_importance_channel', 'high_importance_notification', importance: Importance.max, priority: Priority.max, ), ), ); } }
3. 统一前后台逻辑(可选)
前台的onMessage逻辑可以保持不变,若使用数据消息格式,也可调整为从message.data中获取标题,保持前后台逻辑一致:
FirebaseMessaging.onMessage.listen((RemoteMessage message) async { String? title = message.data['title'] ?? message.notification?.title; String? body = message.data['body'] ?? message.notification?.body; if (title == "attendance" && body != null) { await FlutterLocalNotificationsPlugin().show( message.hashCode, title, body, const NotificationDetails( android: AndroidNotificationDetails( 'high_importance_channel', 'high_importance_notification', importance: Importance.max, priority: Priority.max, ), ), ); } });
关键注意事项
- 后台handler必须是全局顶级函数,不能是类的方法,否则FCM无法正确触发。
- 发送数据消息时,所有通知内容需放在
data字段中,FCM不会自动解析为系统通知,必须手动调用本地通知插件显示。 - 测试后台通知时,需确保App处于后台或被杀死状态,前台逻辑走
onMessage,后台才会触发firebaseMessagingBackgroundHandler。
内容的提问来源于stack exchange,提问作者김건혜
相关产品推荐
相关产品推荐

