当应用程序在后台时,未调用Firebase onmessagerreceived

我正在使用Firebase并测试在应用程序处于后台时从服务器发送通知到我的应用程序。通知发送成功,它甚至出现在设备的通知中心,但当通知出现或即使我点击它,我的FCMessagingService中的onmessagerreceived方法永远不会被调用。

当我测试这个,而我的应用程序是在前台,onmessagerreceived方法被调用,一切工作正常。问题发生在应用程序在后台运行时。

这是我有意为之的行为吗,或者我有办法解决这个问题吗?

这是我的FBMessagingService:

import android.util.Log;


import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;


public class FBMessagingService extends FirebaseMessagingService {


@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.i("PVL", "MESSAGE RECEIVED!!");
if (remoteMessage.getNotification().getBody() != null) {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
} else {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
}
}
}
260173 次浏览

我有这个问题(如果应用程序在后台或关闭,应用程序不想在通知单击时打开),问题是通知正文中的无效click_action,尝试删除或更改为有效的内容。

这是预期的工作,通知消息只有当你的应用程序在前台时才被传递到你的onmessagerreceived回调。如果你的应用程序在后台或关闭,通知消息将显示在通知中心,而任何来自该消息的数据被传递给意图是用户点击通知的结果。

你可以在JSON中指定click_action来指示当用户点击通知时应该启动的意图。如果没有指定click_action,则使用主活动。

当意图启动时,你可以使用

getIntent().getExtras();

检索包含随通知消息一起发送的任何数据的Set。

有关通知消息的更多信息,请参见文档

我也有同样的问题。使用“数据消息”而不是“通知”更容易。数据消息总是加载类onmessagerreceived。

在该类中,您可以使用notificationbuilder创建自己的通知。

例子:

 @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
}


private void sendNotification(String messageTitle,String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);


long[] pattern = {500,500,500,500,500};


Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);


NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setVibrate(pattern)
.setLights(Color.BLUE,1,1)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);


NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
根据Firebase云消息文档-如果Activity在前台,那么onmessagerecreceived将被调用。如果Activity处于后台或关闭,则通知消息将显示在应用程序启动器活动的通知中心。 你可以调用你的自定义活动点击通知,如果你的应用程序是在后台调用rest服务api为firebase消息:

URL -https://fcm.googleapis.com/fcm/send

方法类型- POST

Header- Content-Type:application/json
Authorization:key=your api key

身体/载荷:

{ "notification": {
"title": "Your Title",
"text": "Your Text",
"click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
},
"data": {
"keyname": "any value " //you can get this data as extras in your activity and this data is optional
},
"to" : "to_id(firebase refreshedToken)"
}

在你的应用程序中,你可以添加以下代码在你的活动中被调用:

<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

默认情况下,当你的应用程序在后台,你点击通知时,你应用程序中的发射器的活动将被启动,如果你的通知中有任何数据部分,你可以在相同的活动中处理它,如下所示。

if(getIntent().getExtras()! = null){
//do your stuff
}else{
//do that you normally do
}
我也有同样的问题,在这方面做了更多的挖掘。当应用程序在后台时,通知消息被发送到系统托盘,但是数据信息被发送到onMessageReceived()
看到https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3 < br > 和https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java < / p >

为了确保你正在发送的消息,文档说,"使用您的应用服务器和FCM服务器API:只设置数据键。可以是可折叠的也可以是不可折叠的。"
看到https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages < / p >

消息有两种类型:通知消息和数据消息。 如果你只发送数据消息,那就是在你的消息字符串中没有通知对象。当你的应用程序在后台时,它将被调用

下面是关于firebase消息的更清晰的概念。我从他们的支援组找到的。

Firebase有三种消息类型:

通知消息:通知消息在后台或前台工作。当app在后台时,通知消息被传递到系统托盘。如果应用程序在前台,消息由onMessageReceived()didReceiveRemoteNotification回调处理。这些实质上就是所谓的显示消息。

数据信息:在Android平台上,数据消息可以工作在后台和前台。数据消息将由onMessageReceived()处理。在Android上,数据有效载荷可以在用于启动你的活动的Intent中检索。更详细地说,如果你有"click_action":"launch_Activity_1",你只能通过getIntent()Activity_1中检索这个意图。

同时具有通知和数据有效负载的消息:当在后台时,应用程序在通知托盘中接收通知有效载荷,并且只在用户点击通知时处理数据有效载荷。当在前台,你的应用程序接收到一个消息对象与两个有效负载可用。其次,click_action参数通常用于通知有效负载,而不是数据有效负载。如果在数据有效负载中使用,则此参数将被视为自定义键-值对,因此需要实现自定义逻辑以使其正常工作。

另外,我建议您使用onMessageReceived方法(参见数据消息)来提取数据包。根据您的逻辑,我检查了bundle对象,并没有发现预期的数据内容。这里有一个类似案例的参考,可能会更清楚。

从服务器端,firebase通知应该是波纹格式:

服务器端应该发送“通知”对象。在我的TargetActivity中缺乏“通知”对象,没有使用getIntent()获得消息。

正确的信息格式如下:

{
"data": {
"body": "here is body",
"title": "Title"
},
"notification": {
"body": "here is body",
"title": "Title",
"click_action": "YOUR_ACTION"
},
"to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

下面是关于firebase消息的更清晰的概念。我从他们的支援组找到的。

更多信息请访问我的这个线程这个线程

值得强调的一点是,即使应用程序处于后台,你也必须使用data message - 仅限数据键来调用onmessagerecreceived处理程序。你不应该在你的有效负载中有任何其他通知消息键,否则如果应用程序在后台,处理程序将不会被触发。

这里提到了(但在FCM文档中没有特别强调):

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

使用你的应用服务器和FCM服务器API:可以 可折叠或不可折叠

删除notification字段完全来自你的服务器请求。发送只有data并在onMessageReceived()中处理它,否则当应用程序处于后台或被杀死时,你的onMessageReceived()将不会被触发。

不要忘记在你的通知请求中包含"priority": "high"字段。根据文档:数据消息以正常优先级发送,因此它们不会立即到达;这也可能是问题所在。

这是我从服务器发送的

{
"data":{
"id": 1,
"missedRequests": 5
"addAnyDataHere": 123
},
"to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
"priority": "high"
}

所以你可以像这样接收onMessageReceived(RemoteMessage message)中的数据....假设我需要得到id

Object obj = message.getData().get("id");
if (obj != null) {
int id = Integer.valueOf(obj.toString());
}

后端我正在使用通知消息而不是数据消息。因此,在阅读了所有的答案后,我试图从启动的活动的意图包中检索额外的内容。 但无论我试图从getIntent().getExtras();检索哪个键,该值始终为空。< / p >

然而,我最终找到了一种方法来使用通知消息发送数据并从意图中检索它。

这里的关键是将数据有效载荷添加到通知消息中。

例子:

{
"data": {
"message": "message_body",
"title": "message_title"
},
"notification": {
"body": "test body",
"title": "test title"
},
"to": "E4An.."
}

在你这样做之后,你将能够以这种方式获得你的信息:

< p > intent.getExtras().getString("title") message_title

< p >和 intent.getExtras().getString("message") message_body

参考

在MainActivity的onCreate方法中调用这个:

if (getIntent().getExtras() != null) {
// Call your NotificationActivity here..
Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
startActivity(intent);
}

如果应用程序处于后台模式或非活动(已被杀死),并且你在通知点击,你应该在启动屏幕中检查有效载荷(在我的情况下,启动屏幕是MainActivity.java)。

因此,在MainActivity.java上的onCreate中检查临时演员:

    if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
}
}

如果你的问题与显示大图有关,例如,如果你从firebase控制台发送带有图像的推送通知,它只在应用程序在前台时显示图像。这个问题的解决方案是发送一个只有数据字段的推送消息。就像这样:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }

这个方法handleIntent()已经被贬低了,所以处理通知可以如下所示:

  1. 前台状态:点击通知将转到你在创建通知时提供的pending Intent的活动,因为它通常是用通知的数据负载创建的。

  2. 后台/已终止状态——在这里,系统本身根据通知有效负载创建了一个通知,点击该通知将带你到应用程序的启动器活动,在那里你可以轻松地获取任何生命周期方法中的Intent数据。

覆盖FirebaseMessageServicehandleIntent方法适合我。

这里是c# (Xamarin的)中的代码

public override void HandleIntent(Intent intent)
{
try
{
if (intent.Extras != null)
{
var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");


foreach (string key in intent.Extras.KeySet())
{
builder.AddData(key, intent.Extras.Get(key).ToString());
}


this.OnMessageReceived(builder.Build());
}
else
{
base.HandleIntent(intent);
}
}
catch (Exception)
{
base.HandleIntent(intent);
}
}

这就是Java中的代码

public void handleIntent(Intent intent)
{
try
{
if (intent.getExtras() != null)
{
RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");


for (String key : intent.getExtras().keySet())
{
builder.addData(key, intent.getExtras().get(key).toString());
}


onMessageReceived(builder.build());
}
else
{
super.handleIntent(intent);
}
}
catch (Exception e)
{
super.handleIntent(intent);
}
}

根据t3h Exi的解决方案,我想在这里发布干净的代码。只要把它放入MyFirebaseMessagingService,如果应用程序处于后台模式,一切都可以正常工作。您至少需要编译com.google.firebase:firebase-messaging:10.2.1

 @Override
public void handleIntent(Intent intent)
{
try
{
if (intent.getExtras() != null)
{
RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");


for (String key : intent.getExtras().keySet())
{
builder.addData(key, intent.getExtras().get(key).toString());
}






onMessageReceived(builder.build());
}
else
{
super.handleIntent(intent);
}
}
catch (Exception e)
{
super.handleIntent(intent);
}
}
我也有同样的问题。如果应用程序是前台-它会触发我的后台服务,我可以根据通知类型更新我的数据库。 但是,应用程序将转到后台-默认的通知服务将小心地向用户显示通知。< / p >

下面是我在后台识别应用程序并触发后台服务的解决方案,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {


private static final String TAG = "FirebaseService";


@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "I'm in!!!");


if (intent.getExtras() != null) {
for (String key : intent.getExtras().keySet()) {
Object value = intent.getExtras().get(key);
Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
Bundle bundle = new Bundle();
Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
bundle.putString("push_message", value + "");
backgroundIntent.putExtras(bundle);
context.startService(backgroundIntent);
}
}
}
}
}

在manifest.xml中

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>

在最新的android 8.0版本中测试了该解决方案。谢谢

如果应用程序在后台Fire-base默认处理通知,但如果我们想要我们的自定义通知,那么我们必须改变我们的服务器端,它负责发送我们的自定义数据(数据有效载荷)

从服务器请求中完全删除通知有效负载。只发送数据并在onmessagerecreceived()中处理它,否则当应用程序在后台或被杀死时,你的onmessagerecreceived将不会被触发。

现在,你的服务器端代码格式是这样的,

{
"collapse_key": "CHAT_MESSAGE_CONTACT",
"data": {
"loc_key": "CHAT_MESSAGE_CONTACT",
"loc_args": ["John Doe", "Contact Exchange"],
"text": "John Doe shared a contact in the group Contact Exchange",
"custom": {
"chat_id": 241233,
"msg_id": 123
},
"badge": 1,
"sound": "sound1.mp3",
"mute": true
}
}

请注意:参见上面代码中的这一行
"text": "John Doe在群组联系人交换中共享了一个联系人" 在数据有效载荷中,你应该使用“text”参数而不是“body”或“message”参数来描述消息或任何你想使用文本的参数

onMessageReceived ()

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getData().toString());


if (remoteMessage == null)
return;


// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
/* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
Log.e(TAG, "Data Payload: " + remoteMessage);


try {


Map<String, String> params = remoteMessage.getData();
JSONObject json = new JSONObject(params);
Log.e("JSON_OBJECT", json.toString());




Log.e(TAG, "onMessageReceived: " + json.toString());


handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}

试试这个:

public void handleIntent(Intent intent) {
try {
if (intent.getExtras() != null) {
RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
for (String key : intent.getExtras().keySet()) {
builder.addData(key, intent.getExtras().get(key).toString());
}
onMessageReceived(builder.build());
} else {
super.handleIntent(intent);
}
} catch (Exception e) {
super.handleIntent(intent);
}
}

只需要重写FirebaseMessagingService的OnCreate方法。当你的应用程序在后台时被调用:

public override void OnCreate()
{
// your code
base.OnCreate();
}

当消息收到,你的应用程序是在后台通知被发送到额外的意图的主要活动。

你可以在主活动的oncreate()或onresume()函数中检查额外的值。

您可以检查字段,如数据,表等(在通知中指定的)

例如,我发送使用数据作为关键

public void onResume(){
super.onResume();
if (getIntent().getStringExtra("data")!=null){
fromnotification=true;
Intent i = new Intent(MainActivity.this, Activity2.class);
i.putExtra("notification","notification");
startActivity(i);
}


}

两种类型重火力点推送通知:

< p > 1 -通知消息(显示消息)- > 如果你选择这个变体,如果app在背景中,操作系统将自己创建一个通知,并将传递intent中的数据。然后由客户端来处理这些数据

如果应用程序在前景中,那么通知将通过FirebaseMessagingService中的callback-function接收,并由客户端处理。

数据消息(最多4k数据)->这些消息仅用于将数据发送到客户端(静默),并且由客户端通过FirebaseMessagingService中的回调函数来处理后台/前台两种情况

这是根据官方文档:https://firebase.google.com/docs/cloud-messaging/concept-options

基于以下情况调用onMessageReceived (RemoteMessage RemoteMessage)方法。

  • 包含通知数据块的FCM响应:
{
 
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. 应用程序在前台:

onMessageReceived (RemoteMessage RemoteMessage)调用,在通知栏中显示LargeIcon和BigPicture。我们可以从通知数据块中读取内容

  1. 后台应用:

onMessageReceived (RemoteMessage RemoteMessage)未被调用,系统托盘将接收消息并从通知块读取正文和标题,并在通知栏中显示默认消息和标题。

  • FCM响应只包含数据块:

在本例中,从json中删除通知

{
 
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

调用onmessagerreceived()的解决方案

  1. 应用程序在前台:

onMessageReceived (RemoteMessage RemoteMessage)调用,在通知栏中显示LargeIcon和BigPicture。我们可以从通知数据块中读取内容

  1. 后台应用:

onMessageReceived (RemoteMessage RemoteMessage)调用,系统托盘将不会收到消息,因为通知键不在响应中。在通知栏中显示LargeIcon和BigPicture

代码

 private void sendNotification(Bitmap bitmap,  String title, String
message, PendingIntent resultPendingIntent) {


NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
style.bigPicture(bitmap);


Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);


NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);


notificationManager.createNotificationChannel(notificationChannel);
}
Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
R.drawable.mdmlogo);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.mdmlogo)
.setContentTitle(title)
.setAutoCancel(true)
.setSound(defaultSound)
.setContentText(message)
.setContentIntent(resultPendingIntent)
.setStyle(style)
.setLargeIcon(iconLarge)
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_MAX)
.setChannelId(NOTIFICATION_CHANNEL_ID);




notificationManager.notify(1, notificationBuilder.build());




}

参考链接:

https://firebase.google.com/docs/cloud-messaging/android/receive

看看@Mahesh Kavathiya的答案。对于我的情况,在服务器代码中只有这样:

{
"notification": {
"body": "here is body",
"title": "Title",
},
"to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

您需要更改为:

{
"data": {
"body": "here is body",
"title": "Title",
"click_action": "YOUR_ACTION"
},
"notification": {
"body": "here is body",
"title": "Title"
},
"to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

然后,在case app在后台,默认的活动意图extra将获得“数据”

好运!

我也有类似的问题。根据本页中提到的答案和参考资料,以下是我如何用以下方法解决问题的两点意见:

我之前的消息格式如下:

    {
"notification": {
"title": "AppName",
"sound": null,
"body": "Hey!YouhaveaMessage"
},
"data": {
"param1": null,
"param2": [
238
],
"id": 1
},
"to": "--the device push token here--"
}

我修改了消息格式如下:

    {
"data": {
"title": "AppName",
"body": "Hey! You have a message",
"param1": null,
"param2": [
238
],
"id": 1
},
"priority": "high",
"to": " — device push token here — "
}
然后我检索标题,主体和所有参数从"data"负载本身。这解决了问题,然后我可以得到onmessagerreceived回调,即使应用程序是在后台。 我写了一篇博客文章解释了同样的问题,你可以找到在这里.

我现在回答这个问题可能有点晚了,但是官方文件有点混乱。

它还明确指出,有两种类型的通知

  • 通知消息:由FCM自动处理
  • 数据信息:由客户端应用处理。

毫无疑问,如果服务器发送了一个数据消息,那么onmessagerecreceived()方法肯定会被调用,但在通知消息的情况下,onmessagerecreceived()方法只会在应用程序在前台被调用,当应用程序在后台时,我们发送的数据只是null。

例子:

假设服务器正在发送通知消息类型:

一个。在前台情况下:

  • remoteMessage.data["key"]将工作

B。在背景情况: -remoteMessage.data["key"]将返回null 但在这里,如果你在默认活动中发现相同的意图数据与getIntent().getExtras().getString("key")将工作

C。如果kill: -remoteMessage.data["key"]将返回null 但在这里,如果你在默认活动中发现相同的意图数据与getIntent().getExtras().getString("key")将工作

现在,让我们假设服务器正在发送数据消息类型:

D。在前台情况下:

  • remoteMessage.data["key"]将工作

E。对于背景:

  • remoteMessage.data["key"]将工作

F。如果kill:

  • remoteMessage.data["key"]将工作

毫无疑问,数据消息将总是调用onmessagerreceived()方法,但如果通知消息和应用程序处于后台/kill状态,您可以使用B的解决方案。谢谢

我希望这会节省大家的时间。

{
"notification": {
"title": "Notification Title",
"body": "Notification Body",
"click_action": "ActivityToOpen"
},
"data": {
"key": "value "
},
"to": "id"
}

如果FCM负载有如上的notification{}块,并且应用程序在后台,系统会用notification{}中给出的标题和正文为你构建通知。当用户单击它时,click_action中提到的活动将打开,如果没有给出任何默认启动器活动,则可以访问data{}块中的数据

intent.extras // of the launcher activity

如果应用程序在前台,则会触发FirebaseMessagingService()类中的onMessageReceived()函数。我们将不得不建立自己的通知,我们可以访问数据如下:

val value = message.data.getOrDefault("key", "")

如果FCM负载没有通知块{},如下所示;

{
"data": {
"title": "Notification Title",
"body": "Notification Body",
"key": "value "
},
"to" : "id"
}

函数onmessagerecreceived()在FirebaseMessagingService()类被触发,无论应用程序是在后台或前台,我们将不得不建立自己的通知。

我们可以通过以下方式访问数据:

    override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
val title = message.data.getOrDefault("title", "")
val body = message.data.getOrDefault("body", "")
}

这是预期的行为,你需要在firebase通知数据集中设置click_action,以便能够从后台接收数据。

查看更新答案: https://stackoverflow.com/a/73724040/7904082 < / p >

我认为告诉你将消息类型更改为数据的答案对你来说很清楚。

但有时,如果你不能决定你收到的消息类型,你必须处理它。我把我的方法贴在这里。你刚刚实现了FirebaseMessagingService并在handlIntent ()方法中处理你的消息。从那里你可以自定义你自己的通知。你可以实现自己的方法sendYourNotificatoin()

class FCMPushService : FirebaseMessagingService() {


companion object {
private val TAG = "FCMPush"
}






override fun handleIntent(intent: Intent?) {
Logger.t(TAG).i("handleIntent:${intent.toString()}")
val data = intent?.extras as Bundle
val remoteMessage = RemoteMessage(data)


if (remoteMessage.data.isNotEmpty()) {
val groupId: String = remoteMessage.data[MESSAGE_KEY_GROUP_ID] ?: ""
val title = remoteMessage.notification?.title ?: ""
val body =  remoteMessage.notification?.body ?: ""
if (title.isNotEmpty() && body.isNotEmpty())
sendYourNotificatoin(this, title, body, groupId)
}
}