应用后台时onMessageReceived不触发,如何删除单条FCM通知?
解决FCM后台通知的ID/Tag附加与单条删除问题
嘿,这个问题我之前也碰到过!FCM在后台的行为确实有点坑——当应用处于后台时,系统会直接接管通知展示,不会走onMessageReceived(),导致你没法自定义通知的ID和Tag。不过有几个靠谱的解决方案,我给你梳理一下:
一、给后台通知附加ID和Tag的两种方案
1. 改用「数据消息」触发自定义通知
这是最稳妥的方式:让服务器发送纯数据消息(不带notification字段,只带data字段),这样不管应用在前台还是后台,onMessageReceived()都会被触发,你可以完全自定义通知的ID、Tag以及展示内容。
服务器端示例Payload:
{ "data": { "title": "后台通知标题", "body": "后台通知内容", "tag": "order_update", "id": "1001" }, "to": "你的设备FCM Token", "priority": "high" // 高优先级确保后台也能及时触发 }
客户端onMessageReceived()处理代码:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); // 从data字段中提取Tag和ID String notificationTag = remoteMessage.getData().get("tag"); int notificationId = Integer.parseInt(remoteMessage.getData().get("id")); // 构建自定义通知(记得先创建通知渠道,适配Android 8.0+) NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "YOUR_CHANNEL_ID") .setSmallIcon(R.drawable.ic_notification) .setContentTitle(remoteMessage.getData().get("title")) .setContentText(remoteMessage.getData().get("body")) .setPriority(NotificationCompat.PRIORITY_HIGH) .setTag(notificationTag); // 设置通知Tag // 用指定ID发送通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, builder.build()); }
2. 在通知消息中指定ID(兼容原有通知负载)
如果必须保留notification字段(比如要利用FCM的默认通知展示),可以在通知负载中通过android.notification_id指定ID,同时在data字段中携带Tag:
服务器端示例Payload:
{ "notification": { "title": "后台通知标题", "body": "后台通知内容", "android": { "notification_id": 1001 // 指定通知ID } }, "data": { "tag": "order_update" // 携带Tag }, "to": "你的设备FCM Token" }
这种情况下,系统会自动展示通知,ID就是你指定的1001,Tag则需要在应用启动时(比如用户点击通知进入Activity)从getIntent().getExtras()中获取。
二、根据ID删除单条FCM通知
不管是哪种方案,删除指定ID的通知都很简单,直接调用NotificationManagerCompat的cancel()方法:
代码示例:
// 根据ID删除通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); notificationManager.cancel(notificationId); // notificationId就是你指定的ID // 如果同时用了Tag,也可以按Tag+ID删除 notificationManager.cancel(notificationTag, notificationId);
注意事项
- Android 8.0+必须先创建通知渠道,否则通知无法展示。
- 数据消息要设置
priority: high,否则后台可能延迟接收甚至不触发onMessageReceived()。 - 如果应用被完全杀死,数据消息可能无法触发
onMessageReceived(),这时候可以结合高优先级的通知消息+data字段,在应用启动后处理删除逻辑。
内容的提问来源于stack exchange,提问作者android_jain
相关产品推荐
相关产品推荐

