How to handle notification when app in background in Firebase

To make firebase library to call your onMessageReceived() in the following cases

  1. App in foreground
  2. App in background
  3. App has been killed

you must not put JSON key notification in your request to Firebase API but instead, use data, see below.

The following message will not call your onMessageReceived() when your app is in the background or killed, and you can't customize your notification.

{
   "to": "/topics/journal",
   "notification": {
       "title" : "title",
       "text": "data!",
       "icon": "ic_notification"
    }
}

but instead using this will work

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

Basically, the message is sent in the argument RemoteMessage along with your data object as Map<String, String>, then you can manage the notification in onMessageReceived as in the snippet here

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}

1. Why is this happening?

There are two types of messages in FCM (Firebase Cloud Messaging):

  1. Display Messages: These messages trigger the onMessageReceived() callback only when your app is in foreground
  2. Data Messages: Theses messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed

NOTE: Firebase team have not developed a UI to send data-messages to your devices, yet. You should use your server for sending this type!



2. How to?

To achieve this, you have to perform a POST request to the following URL:

POST https://fcm.googleapis.com/fcm/send

Headers

  • Key: Content-Type, Value: application/json
  • Key: Authorization, Value: key=<your-server-key>

Body using topics

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

Or if you want to send it to specific devices

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


NOTE: Be sure you're not adding JSON key notification
NOTE: To get your server key, you can find it in the firebase console: Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. How to handle the push notification message?

This is how you handle the received message:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}