Here is my manifest

    <service android:name=".fcm.PshycoFirebaseMessagingServices">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <service android:name=".fcm.PshycoFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

When the app is in background and notification arrives then the default notification comes and doesn't run my code of onMessageReceived.

Here is my onMessageReceived code. This invokes if my app is running on foreground, not when app in background. How to run this code when the app is in background too?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]
1 upvote
  flag
Check my answer here, maybe you will get an idea: //allinonescript.com/a/37843845/1507602 – Hisham Muneer
1 upvote
  flag
It's written in the override sample of onMessageReceived(), the second comment line says Not getting messages here? See why this may be: goo.gl/39bRNJ . The solution, like the below answers, can be found in the documentation in Messages with both notification and data payloads – Fllo
upvote
  flag
Shortly speaking, to wake your killed app, you should always send notification with data object to call your notification service class handler FirebaseMessagingService.onMessageReceived() in your application. Also try sending it not from Firebase console, but to post it from somewhere else (e.g. online testing post service). – Zon
upvote
  flag
this solution worked for me //allinonescript.com/a/44150822/6632278 hope helps. Good luck – Tony Barajas

18 Answers 11

According to docs

Handle messages in a backgrounded app

When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload. In these cases, 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.

If you want to open your app and perform a specific action, set click_action in the notification payload and map it to an intent filter in the Activity you want to launch. For example, set click_action to OPEN_ACTIVITY_1 to trigger an intent filter like the following:

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

Edit :

Based on this thread :

You can't set click_action payload using Firebase Console. You could try testing with a curl command or a custom http server

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"/topics/news\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"OPEN_ACTIVITY_1\"}}"
1 upvote
  flag
you are right. i have read the docs. but i m confused where to put this in my manifest ? i have to run the code on the onMessageReceived on that java file so for that what should i have to do sir ? – Parth Patel
upvote
  flag
You can't make the app automatically call onMessageReveiced when it is on background. Instead you need to handle the intent received and make the handler call it. Or probably it is best to implement separate class/method that is called by both onMessageReveiced and your intent handling. I added handler to onNewIntent of the main activity and it works fine for me. – diidu
upvote
  flag
too late to respond to @Parath Patel questions but maybe this will helps someone else with the same problems, take a look to my answer here //allinonescript.com/a/42279260/2734021 – Daniel S.
upvote
  flag
where had to put this action for? for my activity or Firebasemessage service? – Kenji
upvote
  flag
** on multiple notification redirection is not working? eg: if i have three notification from fcm on background using "click_action" first notification redirected successfully and then 2 notification click the activity redirection is not working – prasanthMurugan
up vote 352 down vote accepted

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

Firebase team have not developed a UI to send data-messages to your devices, yet.

2. How to?

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

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

And the following 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
}
upvote
  flag
Hi, apparently if I supply the to key, it works. But when I replace that with a list of device tokens that I wish to send to, aka registration_ids, the notification does not get through. Any ideas? EDIT: I solved it. For some reason, if I remove the sender-id key from my headers, everything works normally. Strange. – Kei
1 upvote
  flag
You can send "data" and "notification" keys in the same notification following these steps //allinonescript.com/a/42279260/2734021 :) – Daniel S.
1 upvote
  flag
If you are sending messages to a Topic, please make sure you have subscribed to the topic on your service. – Rodrigo Garcia
upvote
  flag
If the app is in Background, and you press the notification, it automatically opens the launcher activity, How can you hand the data? – Ali Obeid
upvote
  flag
The app in the background with notification payload is the dumbest thing ever. Is there a practical use for this? 99% the notifications would be sent when your app is in the background to get the user back into your app. – Codeversed
upvote
  flag
You're right, @Codeversed. Maybe if there's few business cases in which you want to send notifications, like exclusive promotions or settings to online users. But definitely there's a small portion of uses... – Antonio
upvote
  flag
I'm using push notifications in Ionic 2 with phonegap plugin and finally I can manage notifications even when the app is killed/bg, thank you very much. I tried to use the field "to" using just 1 device_id and it works, so it's ok also if it's not a topic. – Darko Romanov
1 upvote
  flag
@DarkoRomanov I'm glad that it helped :) – Antonio
2 upvote
  flag
Firebase team have not developed a UI to send data-messages to your devices, yet. Has this changed in the past year? – Hankrecords
upvote
  flag
thank you so much – tej shah
1 upvote
  flag
You are a saviour...!!! 10 upvotes if I can give the answer, nicely explained..!! – Vishavjeet Singh
1 upvote
  flag
@VishavjeetSingh I’m glad it helped! Enjoy your notifications :) – Antonio
1 upvote
  flag
@Antonio thanks for the answer! I was unable to understand what other-key:true means tho. – meagler
1 upvote
  flag
@meagler, thanks for the feedback. Improved my answer to avoid misunderstandings :) – Antonio
upvote
  flag
@Antonio thank you so much! :) – meagler
upvote
  flag
Hi @Antonio I've been trying to figure this out for a long time but haven't been able to solve this problem..so I've posted an independent question here: //allinonescript.com/questions/47990466/… can you check it out? Thanks a lot :) – meagler

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, 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 upvote
  flag
Yes, i did this and perfectly work – Norlihazmey Ghazali
upvote
  flag
Is it possible to achieve this from Firebase console? – koder
upvote
  flag
@koder, unfortunately Firebase console doesn't support this, you have to use tool to send post message request to firebase such as curl or postman(chrome plugin), firebase messaging api please refer to document here - firebase.google.com/docs/cloud-messaging/http-server-ref – Teerakiat Chitawattanarat
upvote
  flag
The notification object should not contain text rather body – Sjd
1 upvote
  flag
this is what I was searching for more than a day..... Thank you so much it worked perfectly. and it would be better if u explain how the key vale pairs in the data can be handled in onMessageReceived() to start a activity with those values. – Boopathi T
8 upvote
  flag
Your method works fine when the app is in background, however when the app is killed I am not receiving data – Sanzhar
3 upvote
  flag
Same problem of Sanzhar. If the app is killed i do not receive any message. – Giacomo Masseroni Chiaro
upvote
  flag
There is no solution/answer when the app is killed. Refer to this 'answer' – newbieguy

According to the firebase documentation in send downstream using firebase, there is 2 type of payload :

  1. data

    This parameter specifies the custom key-value pairs of the message's payload. Client app is responsible for processing data messages. Data messages have only custom key-value pairs.

  2. notification

    This parameter specifies the predefined, user-visible key-value pairs of the notification payload. FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages have a predefined set of user-visible keys.

When you are in the foreground you can get the data inside FCM using onMessageReceived(), you can get your data from data payload.

data = remoteMessage.getData();
String customData = (String) data.get("customData");

When you are in background, FCM will showing notification in system tray based on the info from notification payload. Title, message, and icon which used for the notification on system tray are get from the notification payload.

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification"
       }
}

This notification payload are used when you want to automactically showing notification on the system tray when your app is in the background. To get notification data when your app in the background, you should add click_action inside notification payload.

If you want to open your app and perform a specific action [while backgrounded], set click_action in the notification payload and map it to an intent filter in the Activity you want to launch. For example, set click_action to OPEN_ACTIVITY_1 to trigger an intent filter like the following:

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

Put that intent-filter on your manifest, inside application tag. When you click the notification, it will open the app and go straight to activity that you define in click_action, in this case "OPEN_ACTIVTY_1". And inside that activity you can get the data by :

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

I'm using FCM for my android app and use both of the payload. Here is the example JSON i'm using :

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}
upvote
  flag
@DäñishShärmà you're welcome bro.. – Hendy Evan
upvote
  flag
"Put that intent-filter on your manifest, inside application tag." you can't put intent-filter inside application tag. – Kyrylo Zapylaiev
upvote
  flag
your JSON dows not show where the click_action key goes. – Josh

Here is more clear concepts about firebase message. I found it from their support team.

Firebase has three message types:

Notification messages : Notification message works on background or foreground. When app is in background, Notification messages are delivered to the system tray. If the app is in the foreground, messages are handled by onMessageReceived() or didReceiveRemoteNotification callbacks. These are essentially what is referred to as Display messages.

Data messages: On Android platform, data message can work on background and foreground. The data message will be handled by onMessageReceived(). A platform specific note here would be: On Android, the data payload can be retrieved in the Intent used to launch your activity. To elaborate, if you have "click_action":"launch_Activity_1", you can retrieve this intent through getIntent() from only Activity_1.

Messages with both notification and data payloads: When in the background, apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification. When in the foreground, your app receives a message object with both payloads available. Secondly, the click_action parameter is often used in notification payload and not in data payload. If used inside data payload, this parameter would be treated as custom key-value pair and therefore you would need to implement custom logic for it to work as intended.

Also, I recommend you to use onMessageReceived method (see Data message) to extract the data bundle. From your logic, I checked the bundle object and haven't found expected data content. Here is a reference to a similar case which might provide more clarity.

For more info visit my this thread

1 upvote
  flag
thank you! I feel easy for your explanation. – Hogun

To capture the message in background you need to use a BroadcastReceiver

public class FirebaseDataReceiver extends WakefulBroadcastReceiver {

    private final String TAG = "FirebaseDataReceiver";

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

        Bundle dataBundle = intent.getBundleExtra("data");
        Log.d(TAG, dataBundle.toString());

    }
}

and add this to your manifest:

    <receiver
        android:name="MY_PACKAGE_NAME.FirebaseDataReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </receiver>
2 upvote
  flag
This really receives the notification message, when the app is in background. But it doesn't stop the default Firebase receiver from handling it, so the message still gets displayed as a notification alert. – Galya
upvote
  flag
At the moment doens't work, so that's why I'm proposing this solution. There is a filed bug on the google bugbase. You may want to check that out. – Romulano
upvote
  flag
Could you please post a link to the bug here – Galya
upvote
  flag
how to get data from notification? – Ravi Vaghela
upvote
  flag
This is clearly not working when the app is killed. I have tried this solution for hours. for some reason the receiver is working while the app is in the background and not working when the app is killed – XcodeNOOB
upvote
  flag
Sure, but this is another issue not directly related to this issue XcodeNOOB. – Romulano
upvote
  flag
Getting null. – IntelliJ Amiya
upvote
  flag
Try with intent.getExtras() – Romulano

Remove notification payload completely from your server request. Send only data and handle it in onMessageReceived(), otherwise your onMessageReceived will not be triggered when the app is in background or killed.

Here is what I am sending from server:

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

So you can receive your data in onMessageReceived(RemoteMessage message) like this: (let's say I have to get the id)

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

And similarly you can get any data which you have sent from server within onMessageReceived().

Simple summary like this

  • if your app is running;

    onMessageReceived()
    

is triggers.

  • if your app is not running (killed by swiping) ;

    onMessageReceived()
    

is not triggered and delivered by direclty. If you have any specialy key-value pair. They don' t work beacuse of onMessageReceived() not working.

I' ve found this way;

In your launcher activity, put this logic,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

in this if block, search for your keys according to firebase UI.

In this example my key and value like above; (sorry for language =)) enter image description here

When my code works, i get "com.rda.note".

android.os.Process.killProcess(android.os.Process.myPid());

with this line of code, i closed my application and open Google Play Market

happy coding =)

The easy way to send messages even if the app is in background and foreground as follow:- To send a message using API, you can use a tool called AdvancedREST Client, its a chrome extension, and send a message with the following parameters.

Rest client tool Link: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

use this url:- https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=Your Server key From or Authoization key(see below ref)

{ "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"
}

Authorization key can be obtained by visiting Google developers console and click on Credentials button on the left menu for your project. Among the API keys listed, the server key will be your authorization key.

And you need to put tokenID of the receiver in the “to” section of your POST request sent using API.

Since the display-messages which are sent from Firebase Notification UI only works if your app is in foreground. For data-messages, there is a need to make a POST call to FCM

Steps

  1. Install Advanced Rest Client Google Chrome Extension enter image description here

  2. Add the following headers

    Key: Content-Type, Value: application/json

    Key: Authorization, Value: key="your server key" enter image description here

  3. Add the body

    • If using topics :

    { "to" : "/topics/topic_name", "data": { "key1" : "value1", "key2" : "value2", } }

    • If using registration id :

    { "registration_ids" : "[{"id"},{id1}]", "data": { "key1" : "value1", "key2" : "value2", } }


Thats it!. Now listen to onMessageReceived callback as usual.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}

I feel like all the responses are incomplete but all of them have something that you need to process a notification that have data when your app is in background.

Follow these steps and you will be able to process your notifications when your app is in background.

1.Add an intent-filter like this:

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

to an activity that you want to process the notification data.

  1. Send notifications with the next format:

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }
    

The key here is add

"click_action" : ".MainActivity"

where .MainActivity is the activity with the intent-filter that you added in step 1.

  1. Get "data" info from notification in the onCreate of ".MainActivity":

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //get notification data info
    Bundle bundle = getIntent().getExtras();
    if (bundle != null) {
       //bundle must contain all info sent in "data" field of the notification
    }}
    

And that should be all you need to do. I hope this helps somebody :)

3 upvote
  flag
This should be the correct answer. None of the docs say anything about requiring a click_action AND an Intent Filter for the notification to even show up in the tray. They are both required. – airowe
upvote
  flag
@airowe they are not required for the notification to show up – AlwaysConfused
upvote
  flag
I have both data and notification blocks but i am not able to receive data in activity? – Ashwani
upvote
  flag
have you push notifications working OK in your app? I am not sure how to help you without more information. – Daniel S.
upvote
  flag
Hey there @DanielS. ! I have push notifications working for my app but when the app is in the background, they don't work! I've made all the changes that you've given in this answer. Can you help? Thank you :) – meagler

According to the docs: May 17, 2017

When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, 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.

So,you should use both of the payload notification + data:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

There is no need to use click_action.You should just get exras from intent on LAUNCHER activity

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Java code should be on onCreate method on MainActivity :

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

You can test both of the payload notification + data from Firebase Notifications Console . Don't forget to fill custom data fields on Advanced options section

   @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

}

is not called every time it is called only when app is in forground

there is one override method this method is called every time , no matter what app is in foreground or in background or killed but this method is available with this firebase api version

this is the version u have to import from gradle

compile 'com.google.firebase:firebase-messaging:10.2.1'

this is the method

  @Override
    public void handleIntent(Intent intent) {
        super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

with previous firebase api this method was not there so in that case fire base handle itself when app is in background .... now u have this method what ever u want to do ... u can do it here in this method .....

if you are using previous version than default activity will start in that case u can get data same way

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// do what ever u want .... }

generally this is the structure from server we get in notification

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

it's up to u how u want to give that data key or u want give notification anything u can give ....... what ever u will give here with same key u will get that data .........

there are few cases if u r not sending click action in that case when u will click on notification default activity will open , but if u want to open your specific activity when app is in background u can call your activity from this on handleIntent method because this is called every time

upvote
  flag
I updated the firebase-messaging to 10.2.1, Added Data to the notification message, and it worked. Foreground, Background, and Killed. Thanks – F.sh
upvote
  flag
in Kotlin, i get this Error:(44, 5) 'handleIntent' in 'FirebaseMessagingService' is final and cannot be overridden – ugali soft
upvote
  flag
this hack already didn't work with fcm version 11.6.0 – Эвансгелист Evansgelist

2017 updated answer

Here is a clear-cut answer from the docs regarding this:

enter image description here

I figured out the scenarios,

When app is in foreground, onMessageReceived() method is called from the FirebaseService.So the pendingIntent defined in the service class will be called.

And when app is in background, first activity is called.

Now, if you use a splash activity, then must keep in mind the splashactivity will be called, else if there is no splashActivity, then whatever the first activity is, will be called.

Then you need to check getIntent() of the firstActivity to see if it has any bundle .if everything is alright you will see bundle is there with values filled in. If the value in data tag sent from server looks like this,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

Then in the first activity, you will see, there is a valid intent( getIntent() is not null) , valid bundle and inside bundle , there will the whole JSON mentioned above with data as key.

For this scenario, code for extraction of value will look like this,

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }

I've experienced the same problem and recompiled the firebase library and prevented it from sending notifications when the application is in the background

*library https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

hope helps. Good luck

i have mail fcm support and give me solution. fcm support mail receive on 14-12-2017

i am sending notification message with data payload through fcm console. onMessageReceived() call only app foreground(current open app), when app background data message comes only through intent value in launcher activity. i have add some step you can understand easy .

first i am sending notification with data through firebase console

this notifiaction come perfectly when app is open that means forground app .

but when app is not open at that time notification come but data not receive onMessageReceived() method. this problem i have found new solution , this below code on my main launcher activity. i am getting data when notification come and app is background and user tap on notification.

this code i have put on my main activity

if (getIntent().getExtras() != null) {

        for (String key : getIntent().getExtras().keySet()) {
            String value = getIntent().getExtras().getString(key);

            if (key.equals("chirag")) {
                //Intent intent = new Intent(this, AnotherActivity.class);
                //intent.putExtra("value", value);
                //startActivity(intent);
                //finish();
                txtMsg.setText(value+" :- this is notification .");

            }

        }
    }
    else {

    }

but app background and more than one notification come , at this time every separate notification . but i want inbox style notification.

Thanks to All of you for your Answers. But I solved this by sending data message instead of sending Notification. Server code

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

and caught the Data in onMessageReceived

 @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

      sendNotification(remoteMessage.getData().get("message"));

   // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    sendNotification(remoteMessage.getNotification().getBody());
    }


}

Not the answer you're looking for? Browse other questions tagged or ask your own question.