Flutter Awesome Notifications重复通知及按钮ID获取求助
一、重复通知问题修复
问题根源
重复通知是因为Firebase Messaging会自动生成通知,同时你在Firebase的消息回调中又调用了Awesome Notifications的showNotification,导致两条通知叠加:一条是Firebase原生无按钮通知,一条是Awesome Notifications生成的带按钮通知。即使移除按钮,Firebase的自动通知依然会触发。
修复步骤
1. 禁用Firebase前台自动弹窗
修改setForegroundNotificationPresentationOptions,关闭Firebase的前台自动通知展示,完全由Awesome Notifications接管:
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: false, // 关键:关闭Firebase前台自动弹窗 badge: true, sound: true, );
2. 移除冗余的showNotification调用
getInitialMessage和onMessageOpenedApp是处理用户点击通知打开应用的场景,不需要再次发送通知,直接处理业务逻辑即可:
// 修改getInitialMessage回调 FirebaseMessaging.instance.getInitialMessage().then((value) { if (value != null) { // 这里处理冷启动跳转逻辑,不要调用showNotification log(value.data["notification_id"]); } }); // 修改onMessageOpenedApp回调 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { // 这里处理后台唤醒跳转逻辑,不要调用showNotification log(message.data["notification_id"]); });
3. 后台消息处理优化
确保_firebaseMessagingBackgroundHandler中优先初始化Firebase,并且只处理自定义逻辑,避免Firebase自动发通知。建议推送时使用纯Data消息(不要填Firebase的Notification字段),这样Firebase不会自动弹通知:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { // 初始化要放在最前面 await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); if (message.data.isNotEmpty) { NotificationService.showNotification( title: message.data["title"] ?? "", body: message.data["body"] ?? "", actionButtons: actionButtons, payload: {"notification_id": message.data["notification_id"] ?? ""} ); } }
二、点击按钮获取notification_id
1. 传递notification_id到Awesome Notifications
在调用showNotification时,把Firebase消息中的notification_id作为payload参数传入:
// onMessage回调示例修改 FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (message.data.isNotEmpty) { NotificationService.showNotification( title: message.data["title"] ?? message.notification?.title ?? "", body: message.data["body"] ?? message.notification?.body ?? "", actionButtons: actionButtons, payload: {"notification_id": message.data["notification_id"] ?? ""} ); } });
2. 在按钮点击回调中获取ID
直接通过receivedAction.payload读取,不需要转成字符串:
static Future<void> onActionReceivedMethod( ReceivedAction receivedAction) async { debugPrint('onActionReceivedMethod'); // 直接从payload中提取notification_id final notificationId = receivedAction.payload?['notification_id']; if (notificationId != null) { log('Notification ID: $notificationId'); // 这里可以执行后续API调用逻辑 } }
额外优化:确保通知ID唯一
当前showNotification中NotificationContent的id设为-1,Awesome Notifications会自动生成唯一ID,你也可以用notification_id作为通知ID,避免潜在重复:
content: NotificationContent( id: int.tryParse(message.data["notification_id"] ?? "-1") ?? -1, channelKey: 'high_importance_channel', // ...其他参数 ),
内容的提问来源于stack exchange,提问作者RIZWAN ALI

