FCM通知在后台/应用杀死时onMessageReceived()未调用问题咨询
解决FCM后台/应用杀死状态下onMessageReceived不触发的问题
嘿,这个问题我之前踩过坑!其实核心原因是FCM的两种消息类型在后台/前台的处理逻辑不一样,咱们一步步来解决:
首先得搞懂FCM的两种消息模式:
- 通知消息:由FCM服务器直接处理,当应用在后台或被杀死时,系统会自动把通知展示在通知栏,但不会调用你的
onMessageReceived()方法——这就是你现在遇到的情况。 - 数据消息:完全由你的应用代码接管,不管应用是前台、后台还是被杀死,都会触发
onMessageReceived(),但需要你自己写代码来展示通知。
方案1:后台也触发onMessageReceived,同时自定义通知
如果你希望不管应用状态如何,都能触发onMessageReceived(),那后端发送消息时,不要用FCM的notification字段,把所有内容都放到data字段里。比如后端的请求payload应该是这样的:
{ "to": "目标设备的令牌", "data": { "title": "你的通知标题", "body": "你的通知内容", "custom_param": "你需要的自定义数据" } }
然后在你的FirebaseMessagingService的onMessageReceived()方法里,自己构建并显示通知:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // 从data字段里取出内容 String title = remoteMessage.getData().get("title"); String body = remoteMessage.getData().get("body"); String customParam = remoteMessage.getData().get("custom_param"); // 构建通知(记得先创建通知渠道,适配Android 8.0+) NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "你的通知渠道ID") .setSmallIcon(R.drawable.ic_notification_icon) .setContentTitle(title) .setContentText(body) .setPriority(NotificationCompat.PRIORITY_HIGH); // 显示通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(1001, builder.build()); // 这里可以处理你的自定义逻辑,比如更新本地数据之类的 }
方案2:保留系统自动展示通知,但仍要获取数据
如果你想保留FCM自动展示通知的功能,同时还要在后台获取数据,那可以发送通知+数据的混合消息。不过要注意:
- 应用前台:
onMessageReceived()会拿到完整的消息(包括notification和data字段) - 应用后台/被杀死:系统会展示
notification里的内容,但onMessageReceived()只会收到data字段;如果用户点击通知打开应用,你需要从启动Activity的Intent里获取相关数据。
后端的payload示例:
{ "to": "目标设备的令牌", "notification": { "title": "系统通知标题", "body": "系统通知内容" }, "data": { "custom_param": "你需要的自定义数据" } }
然后在启动的Activity里获取数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); if (intent != null && intent.getExtras() != null) { String customParam = intent.getExtras().getString("custom_param"); // 在这里处理你的自定义逻辑 } }
最后还要检查几个容易踩的坑:
- 确保你的
FirebaseMessagingService在AndroidManifest里正确注册了:
<service android:name=".你的FirebaseMessagingService子类" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
- 不要在
onMessageReceived()里做耗时操作,超过10秒可能会被系统终止,必要时用WorkManager来处理异步任务。
内容的提问来源于stack exchange,提问作者Tharun
相关产品推荐
相关产品推荐

