Open app on firebase notification received (FCM)

It looks like this section of the guide is the key to the puzzle of backgrounded apps:

To receive messages
Use a service that extends FirebaseMessagingService. Your service should override the onMessageReceived callback, which is provided for most message types, with the following exceptions:

Notifications delivered when your app is in the background.
In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.

Messages with both notification and data payload.
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.

Essentially, when the app is backgrounded, it's not truly responsive or running at this point. So instead, the message is delivered to the system tray. However, just below, the solution is explained.

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>

Quick answer:

To automatically open an application via FCM you need to use a data-message, which guarantees to always invoke the FirebaseMessagingService.onMessageReceived() method.

Then you can add your logic in the .onMessageReceived() method to start the preferred activity.

WARNING: launching a UI without any user interaction is a very very bad practice for most of the applications! Please read the MarkG answer here: How to start an Activity from a Service?

[...] Interrupting what the user is currently doing is considered bad design form, especially from something that is supposed to be operating in the background.
Therefore, you should consider using a Notification [...] to launch the desired Activity when the user decides it is time to investigate. [...]

Full explaination:

FCM works similarly to GCM and can receive two types of messages:

  1. display-messages:
    payload {"notification" : { "body" : "hello world"}}
    These messages are automatically displayed when the app is in background and they call FirebaseMessagingService.onMessageReceived() if the app is already in foreground.

  2. data-messages:
    payload {"data" : { "key1" : "value1"}}
    These messages always invoke FirebaseMessagingService.onMessageReceived(),
    even if the app is closed or in background.

click_action is a parameter of the notification payload, thus it applies to the display-messages.

Indicates the action associated with a user click on the notification.
If this is set an activity with a matching intent filter is launched when user clicks the notification.

https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support


I summarize the steps here, hopefully it helpful

STEP 1

Following FCM user guide. Make sure everything work properly by pushing a message from Firebase console.

STEP 2

Change your custom FirebaseMessagingService class as following:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());
    startActivity(new Intent(this, SplashActivity.class));
}
}

Now using Firebase console push messages again, you will found that onMessageReceived only fires when your app is in the foreground. Because Firebase console is able to send Notification message only. In order to send Data message, we need step 3.

STEP 3

Install Google Advanced REST client

Input below params:

url: https://fcm.googleapis.com/fcm/send
method: POST 
Raw header: 
Content-Type: application/json
Authorization:key=YOUR_SERVER_KEY
Raw payload:
{
   "to" : "YOUR_DEVICE_FCM_TOKEN",
   "data" : {
     "Nick" : "Mario",
     "body" : "great match!",
     "Room" : "PortugalVSDenmark"
   },
 } 

YOUR_SERVER_KEY is available in the Firebase console > Settings pane > the Cloud Messaging tab

YOUR_DEVICE_FCM_TOKEN is FirebaseInstanceId.getInstance().getToken() on onTokenRefresh()

NOTE

Starting UI without user interaction is bad UX, you might need to replace start activity with start service or something in the background. I just use activity for testing purpose, so it will be more visual than service. Thanks @2ndgab for introducing to the Google Advanced REST client tool.