Firebase FCM notifications click_action payload

The question:

I am trying to open a particular activity when the user clicks the notification when the app is in the background. From the Docs, I have got that click_action has to be added in the payload and an intent filter in the App to handle it. But, how to add click_action in the Firebase Notifications via Firebase Console? I am open to any other Work Around too. Thanks in Advance.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

If your app is in background, Firebase will not trigger onMessageReceived(). Why…..? I have no idea. In this situation, I do not see any point in implementing FirebaseMessagingService.

According to docs, if you want to process background message arrival, you have to send ‘click_action’ with your message.
But it is not possible if you send message from Firebase console, only via Firebase API.
It means you will have to build your own “console” in order to enable marketing people to use it. So, this makes Firebase console also quite useless!

There is really good, promising, idea behind this new tool, but executed badly.

I suppose we will have to wait for new versions and improvements/fixes!

Method 2

As far as I can tell, at this point it is not possible to set click_action in the console.

While not a strict answer to how to get the click_action set in the console, you can use curl as an alternative:

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" --header Content-Type:"application/json"  -d "{"to":"/topics/news","notification": {"title": "Click Action Message","text": "Sample message","click_action":"OPEN_ACTIVITY_1"}}"

This is an easy way to test click_action mapping. It requires an intent filter like the one specified in the FCM docs:

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

This also makes use of topics to set the audience. In order for this to work you will need to subscribe to a topic called “news”.


Even though it takes several hours to see a newly-created topic in the console, you may still send messages to it through the FCM apis.

Also, keep in mind, this will only work if the app is in the background. If it is in the foreground you will need to implement an extension of FirebaseMessagingService. In the onMessageReceived method, you will need to manually navigate to your click_action target:

public void onMessageReceived(RemoteMessage remoteMessage) {
    //This will give you the topic string from curl request (/topics/news)
    Log.d(TAG, "From: " + remoteMessage.getFrom());
    //This will give you the Text property in the curl request(Sample Message): 
    Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
    //This is where you get your click_action 
    Log.d(TAG, "Notification Click Action: " + remoteMessage.getNotification().getClickAction());
    //put code here to navigate based on click_action

As I said, at this time I cannot find a way to access notification payload properties through the console, but I thought this work around might be helpful.

Method 3

You can handle all your actions in function of your message in onMessageReceived() in your service extending FirebaseMessagingService.
In order to do that, you must send a message containing exclusively data, using for example Advanced REST client in Chrome.
Then you send a POST to
using in “Raw headers”:

Content-Type: application/json

And a json message in the field “Raw payload”.

Warning, if there is the field “notification” in your json, your message will never be received when app in background in onMessageReceived(), even if there is a data field !
For example, doing that, message work just if app in foreground:

    "condition": " 'Symulti' in topics || 'SymultiLite' in topics",
    "priority" : "normal",
    "time_to_live" : 0,
    "notification" : {
        "body" : "new Symulti update !",
        "title" : "new Symulti update !",
        "icon" : "ic_notif_symulti"
    "data" : {
        "id" : 1,
        "text" : "new Symulti update !"

In order to receive your message in all cases in onMessageReceived(), simply remove the “notification” field from your json !


    "condition": " 'Symulti' in topics || 'SymultiLite' in topics",
    "priority" : "normal",
    "time_to_live" : 0,,
    "data" : {
        "id" : 1,
        "text" : "new Symulti update !",
        "link" : "href://"

and in your FirebaseMessagingService :

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    public void onMessageReceived(RemoteMessage remoteMessage) {
      String message = "";
      obj = remoteMessage.getData().get("text");
      if (obj != null) {
        try {
          message = obj.toString();
        } catch (Exception e) {
          message = "";

      String link = "";
      obj = remoteMessage.getData().get("link");
      if (obj != null) {
        try {
          link = (String) obj;
        } catch (Exception e) {
          link = "";

      Intent intent;
      PendingIntent pendingIntent;
      if (link.equals("")) { // Simply run your activity
        intent = new Intent(this, MainActivity.class);
      } else { // open a link
        String url = "";
        if (!link.equals("")) {
          intent = new Intent(Intent.ACTION_VIEW);
      pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,

      NotificationCompat.Builder notificationBuilder = null;

      try {
        notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_notif_symulti)          // don't need to pass icon with your message if it's already in your app !
            .setContentTitle(URLDecoder.decode(getString(R.string.app_name), "UTF-8"))
            .setContentText(URLDecoder.decode(message, "UTF-8"))
        } catch (UnsupportedEncodingException e) {

        if (notificationBuilder != null) {
          NotificationManager notificationManager =
              (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        } else {
          Log.d(TAG, "error NotificationManager");

Enjoy !

Method 4

This falls into workaround category, containing some extra information too:

Since the notifications are handled differently depending on the state of the app (foreground/background/not launched) I’ve seen the best way to implement a helper class where the selected activity is launched based on the custom data sent in the notification message.

  • when the app is on foreground use the helper class in onMessageReceived
  • when the app is on background use the helper class for handling the intent in main activity’s onNewIntent (check for specific custom data)
  • when the app is not running use the helper class for handling the intent in main activity’s onCreate (call getIntent for the intent).

This way you do not need the click_action or intent filter specific to it. Also you write the code just once and can reasonably easily start any activity.

So the minimum custom data would look something like this:

Key: run_activity
Value: com.mypackage.myactivity

And the code for handling it:

if (intent.hasExtra("run_activity")) {

private void handleFirebaseNotificationIntent(Intent intent){
    String className = intent.getStringExtra("run_activity");
    startSelectedActivity(className, intent.getExtras());

private void startSelectedActivity(String className, Bundle extras){
    Class cls;
    try {
        cls = Class.forName(className);
    }catch(ClassNotFoundException e){
    Intent i = new Intent(context, cls);

    if (i != null) {

That is the code for the last two cases, startSelectedActivity would be called also from onMessageReceived (first case).

The limitation is that all the data in the intent extras are strings, so you may need to handle that somehow in the activity itself. Also, this is simplified, you probably don’t what to change the Activity/View on an app that is on the foreground without warning your user.

Method 5

Well this is clear from firebase docs that your onMessageReceived will not work when app is in background.

When your app is in background and click on your notification your default launcher will be launched.
To launch your desired activity you need to specify click_action in your notification payload.

$noti = array
    'icon' => 'new',
    'title' => 'title',
    'body' => 'new msg',
    'click_action' => 'your activity name comes here'

And in your android.manifest file

Add the following code where you registered your activity

                android:name="your activity name">
                    <action android:name="your activity name" />
                   <category android:name="android.intent.category.DEFAULT"/>

Method 6

If your app is in background, Firebase will not trigger onMessageReceived().
onMessageReceived() is called when app is in foreground .
When app is in background,onMessageReceived() method will be called only if the body of contain only data payload.Here ,i just created a method to build custom notification with intent having ur your required activity . and called this method in onMessageRecevied() .

In PostMan:


header:Authorization:key=ur key

body —>>

{  "data" : {
      "Nick" : "Mario",
      "Room" : "PoSDenmark",


  "to" : "xxxxxxxxx"


in your application.

class MyFirebaseMessagingService  extends FirebaseMessagingService {

 public void onMessageReceived(RemoteMessage remoteMessage) {
       if (remoteMessage.getData().size() > 0) {
           sendNotification("ur message body") ;
private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, Main2Activity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("FCM Message")

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */,;


when the data payload comes to the mobile,then onMessageReceived() method will be called.. inside that method ,i just made a custom notification. this will work even if ur app is background or foreground.

Method 7


So just to verify, it is not currently possible to set the click_action parameter via the Firebase Console.

So I’ve been trying to do this in the Firebase Notifications Console with no luck. Since I can’t seem to find anywhere to place the click_action value in the console, what I mainly did to test this out is to add a custom key/value pair in the Notification (Advance Options > Custom Data):

Key: click_action
Value: <your_preferred_value>

then tried calling RemoteMessage.getNotification().getClickAction() in onMessageReceived() to see if it was retrieving the correct value, but it always returns null. So next I tried calling RemoteMessage.getData().get(< specified_key >) and was able to retrieve the value I added.

NOTE: I am not entirely sure if that is okay to be used as a workaround, or if it’s against best practice. I would suggest using your own app server but your post is specific to the Firebase Console.

The way the client app and the notification behaves still depends on how you program it. With that said, I think you can use the above as a workaround, using the value retrieved from the getData(), then having the Notification call this or that. Hope this helps somehow. Cheers! 😀

Method 8

Now it is possible to set click_action in Firebase Console. You just go to notifications-send message-advanced option and there you will have two fields for key and value. In first field you put click_action and in second you put some text which represents value of that action. And you add intent-filter in your Manifest and give him the same value as you wrote in console.
And that is simulation of real click_action.

Method 9

there is dual method for fcm
fcm messaging notification and app notification
in first your app reciever only message notification with body ,title and you can add color ,vibration not working,sound default.
in 2nd you can full control what happen when you recieve message example
onMessageReciever(RemoteMessage rMessage){ notification.setContentTitle(rMessage.getData().get("yourKey")); }
you will recieve data with(yourKey)
but that not from fcm message
that from fcm cloud functions

Method 10

In Web, simply add the url you want to open:

  "condition": "'test-topic' in topics || 'test-topic-2' in topics",  
  "notification": {
            "title": "FCM Message with condition and link",
            "body": "This is a Firebase Cloud Messaging Topic Message!",            
            "click_action": ""

Method 11

One simple work around is, in the fcm options – add / as the link value, the background notification click will be redirected to the app.

Method 12

I’m looking this Firebase is , development from google cloud messaging push notification fundamental so we can use the gcm tutorial,function and implementation in firebase ,
i using funtion of gcm push notification function to solve this click_action problem
i use gcm function **


try this save url click_action in variable url this is in server-worker.js

var url =  "";

messaging.setBackgroundMessageHandler(function(payload) {

  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  url =;

  const notificationTitle =;
  const notificationOptions = {
    body: , 
    icon: 'firebase-logo.png'

  return self.registration.showNotification(notificationTitle,


   //i got this in google cloud messaging push notification

self.addEventListener('notificationclick', function (event) {

  var clickResponsePromise = Promise.resolve();
    clickResponsePromise = clients.openWindow(url);


All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment