5

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
}
Akli
  • 1,351
  • 1
  • 15
  • 28
  • 1
    Please can you share the JSON of your fcm which you are using to send data and notification? – Nishant Dubey Sep 29 '16 at 20:03
  • Also are you putting all this code here ? `// Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); //and your other code i.e intents and all }` – Nishant Dubey Sep 29 '16 at 20:07
  • Can you tell me the maker or model of phone you testing this on. Because many manufactures **(specially those based in china)** have weird background service kill apps in their architecture which cause lot of problems with services background apps and more. Just a slight concern that even that might be an issue here. – Nishant Dubey Sep 29 '16 at 20:50
  • You might have a point, I am testing with Visual Studio Emulators. I am going to test with a real device. – Akli Sep 29 '16 at 20:56
  • 1
    Repeating the first comment, could you please extend the question with the payload you send to FCM? This is really important, as the Android client behaves differently depending on which payload types (data and/or notification) you include. – vzsg Sep 30 '16 at 08:00
  • @Nishant, could you post Edit3 as an answer? I think you pointed that out the first time. – Akli Sep 30 '16 at 12:04
  • @Akli I just posted. I think now you already know the solution. Good luck :) – Nishant Dubey Sep 30 '16 at 16:12
  • @Akli Please try the edited suggestion first which I just wrote in my answer. If that works then **you can send both Notification and Data** payloads. But yes that is true only if your action requires user to launch MainActivity. Otherwise the main solution for onMessageReceived() is the way. But you surely can intercept intent on app launch from notification click even if json has both Notification and Data payload. – Nishant Dubey Sep 30 '16 at 21:02

2 Answers2

3

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.

vzsg
  • 2,831
  • 17
  • 20
2

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.

Nishant Dubey
  • 2,802
  • 1
  • 13
  • 18
  • Thanks for really important information, I found out that it is not necessary to use it in launcher activity. inside the firebase service you are pushing this data to a specific intent. there you may use but really important thing is if you put a Notification payload. it is not waking up and do the things you need. only data is working – Alp Altunel Oct 25 '19 at 07:04