我正在使用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"));
        }
    }
}

当前回答

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

但有时,如果你不能决定你收到的消息类型,你必须处理它。我把我的方法贴在这里。您刚刚实现了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)
    }
}

}

其他回答

基于以下情况调用的onmessagerecreceived (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"
  }
}

应用程序在前台:

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

后台应用:

onmessagerreceived (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()的解决方案

应用程序在前台:

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

后台应用:

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

Code

 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

我也有同样的问题,在这方面做了更多的研究。当应用程序在后台时,通知消息被发送到系统托盘,但数据消息被发送到onmessagerreceived () 看到https://firebase.google.com/docs/cloud-messaging/downstream monitor-token-generation_3 和https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

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

我有这个问题(应用程序不想打开通知点击,如果应用程序是在后台或关闭),问题是在通知主体无效的click_action,尝试删除或更改为有效的东西。

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

你可以在主活动的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);
        }

}

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

请看这里更新的答案: https://stackoverflow.com/a/73724040/7904082