Flutter场景下如何获取FCM通知对应的Android通知ID?
解决FCM通知ID无法获取的问题
以下是几个在Flutter层面处理的可行方案:
方案1:自定义通知展示流程,掌控通知ID
FCM默认推送的通知由Android系统直接展示,这种情况下Flutter确实拿不到通知ID。可以改用**数据消息(Data Message)**形式推送,由前端自行处理通知展示,从而自定义并保存通知ID:
- 后端推送FCM消息时,将通知内容放在
data字段而非notification字段。 - Flutter端监听FCM的
onMessage回调,接收到数据后,用flutter_local_notifications生成自定义通知ID(比如时间戳、自增整数),调用show()方法展示通知,同时把ID存在本地(如SharedPreferences)。 - 后续需要清除时,直接调用
flutter_local_notifications的cancel(通知ID)方法即可。
示例代码片段:
// 监听FCM数据消息 FirebaseMessaging.onMessage.listen((RemoteMessage message) { final notificationId = DateTime.now().millisecondsSinceEpoch; // 生成唯一ID // 保存ID到本地 SharedPreferences.getInstance().then((prefs) { prefs.setInt('last_notification_id', notificationId); }); // 用flutter_local_notifications展示通知 flutterLocalNotificationsPlugin.show( notificationId, message.data['title'], message.data['body'], NotificationDetails( android: AndroidNotificationDetails( 'your_channel_id', 'your_channel_name', importance: Importance.max, ), ), ); }); // 清除通知时 final prefs = await SharedPreferences.getInstance(); final id = prefs.getInt('last_notification_id'); if (id != null) { await flutterLocalNotificationsPlugin.cancel(id); }
方案2:通过Android原生层获取通知ID(MethodChannel)
如果必须使用FCM默认通知展示,可以通过Android原生代码捕获通知ID,再通过MethodChannel传给Flutter:
- 在Android项目的
FirebaseMessagingService子类中,重写onMessageReceived方法。FCM推送通知时,系统会生成通知ID,在这里捕获ID并通过MethodChannel发送给Flutter。 - Flutter端调用MethodChannel获取保存的ID,再用
flutter_local_notifications的cancel()方法清除。
Android原生代码示例:
class MyFirebaseMessagingService : FirebaseMessagingService() { private val CHANNEL_ID = "fcm_default_channel" private var notificationId = 0 override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 生成通知ID notificationId = (System.currentTimeMillis() / 1000).toInt() // 发送ID到Flutter val channel = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "com.example/notification_id") channel.invokeMethod("getNotificationId", notificationId) // 展示通知(模仿FCM默认逻辑) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(remoteMessage.notification?.title) .setContentText(remoteMessage.notification?.body) .setPriority(NotificationCompat.PRIORITY_HIGH) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.notify(notificationId, notificationBuilder.build()) } }
Flutter端代码:
final MethodChannel _channel = MethodChannel('com.example/notification_id'); int? _notificationId; @override void initState() { super.initState(); _channel.setMethodCallHandler((call) async { if (call.method == 'getNotificationId') { _notificationId = call.arguments as int; } }); } // 清除通知 if (_notificationId != null) { await flutterLocalNotificationsPlugin.cancel(_notificationId!); }
方案3:批量清除所有FCM通知
如果不需要精准清除单个通知,可以直接调用flutter_local_notifications的cancelAll()方法,或者通过MethodChannel调用Android原生的NotificationManager.cancelAll()清除所有通知:
// 用flutter_local_notifications批量清除 await flutterLocalNotificationsPlugin.cancelAll(); // 或者通过原生MethodChannel调用 final MethodChannel _channel = MethodChannel('com.example/notification'); await _channel.invokeMethod('cancelAllNotifications');
内容的提问来源于stack exchange,提问作者Scorb
相关产品推荐
相关产品推荐

