FirebaseMessagingService : intent.putExtra() does

2019-06-23 14:54发布

问题:

EDIT3: Ok I found the problem : If the app is killed, sending both data and notification won't trigger onMessageReceived. notification needs to be set to null if the target device is android.

That's really a dumb behaviour.

Original post:

I can successfully retrieve the bundle from the intent passed by the notificationBuilder to the activity when the app is launched.

However, if I kill the app, the notification still works but the GetExtras() from the intent is null.

In my FirebaseMessagingService child class:

@Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
     Intent intent  = new Intent(this, MainActivity.class);        
     intent.putExtra("key_1","value");
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    //also tried with  PendingIntent.FLAG_CANCEL_CURRENT


     Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("title")
            .setContentText("messageBody")
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, notificationBuilder.build());

}

When the app is killed, the firebaseMessagingService can't even write a file. It does not crash, it builds, and shows the notification, but anything done to the disk does not work.

EDIT: I have replaced the content of the onMessageReceived method as follows:

@Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
     // Do nothing
}

When the app is running nothing happens -as expected- but when the app is killed a notification is displayed whith the name app as a title and remoteMessage.getNotification().getBody() as content text.

It seems that onMessageReceived is not fired. Instead another magic function is called...

EDIT2: As requested, this is what is sent from the server:

{
    "data":
     {
          "form_id":"33882606580812",
          "recipientUserId":10500
     }
     ,
     "to":"e0bU2jIVO9g:APA91bHsS-s3G1gQLcTFtRUC77pJUWcZvD7h9NfUgFLD-bFam1S0dddngVcmrQlXR5i6DfTsc69T8JbIrSuzyF1iv0c4ac1gmkwvGVMwZo_yA4KwOh82Nx-weYeL79r79si4qH3QBEgs",
     "notification":
     {
          "body":"you have a new notification",
          "badge":"1",
          "sound":"default"
     },
     "delay_while_idle":false
}

回答1:

My first answer to your question which I ended up deleting as we both felt that in your case onMessageReceived() is called. But this is what it really is

onMessageReceived() method will not be called if the app is in background or killed and if the message sent contains DATA and NOTIFICATION payload both.

When app is not running you will anyway receive notification. But if you want to intercept data via onMessageReceived() then you will have to create a custom app server which will send only DATA payload to fcm endpoint.

something like this:

    {
   "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "data" : {
     "Title" : "Title for Notification",
     "body" : "Notification body can go here",
     "Room" : "Something extra"
   },
 }

Hope this solves your issue.

EDIT: I just realized that if you want to send Notification and Data payload both while app is killed and in background then intent can be intercepted in launcher activity when user clicks on notification. By simply doing this:

Intent fcmIntent = getIntent();

But this will work only in Launcher Activity which the notification click is launching. You can simply put it in onCreate() method.



回答2:

After your second edit, we can see that you send both a notification and a data payload to FCM. If you check the FCM Documentation, you can see how the application will behave depending on being in the foreground or in the background. (Having your application killed is the same as running in the background.)

[Exception 2] Messages with both notification and data payload, both background and foreground. In this case, the notification is delivered to the device’s system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.

This means that your onMessageReceived method is never called in this state. The FCM service internally creates a notification that starts your main activity and passes the data payload in the intent bundle automatically.

You should either handle this situation correctly, or use only data payloads to opt out of the built-in behavior.