Open app on firebase notification received (FCM)

67,837

Solution 1

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

Solution 2

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>

Solution 3

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.

Solution 4

[Android] If you are using Firebase Notifications (not Firebase Cloud Messaging) all you have to do is include Firebase Messaging in your build.gradle, and then link your app to a project on Firebase Console.

If your app is in the background, any message sent from the console will give you a system notifiction, which, if touched, will activate your app.

Take a look here: https://youtu.be/KpTSpVh9SfY?t=10m22s

Share:
67,837
stevyhacker
Author by

stevyhacker

Android developer, tech geek

Updated on July 09, 2022

Comments

  • stevyhacker
    stevyhacker almost 2 years

    I want to open application automatically when notification is received, is this possible with Firebase and new FCM notifications?

    I know I can set click_action but that's only for customizing which activity will start on notification click, I need something that will start automatically when notification is received.

    I tried the quick start messaging firebase sample and there is a onMessageReceived() method but it only works if the app is in foreground. Is there something that will execute while app is in background as well? GCM could do something like what I want here by directly starting activity intent from broadcast receiver which is called when notification is received.

  • stevyhacker
    stevyhacker almost 8 years
    I will try this again but I think click_action implies what activity will run on clicking the notification.
  • stevyhacker
    stevyhacker almost 8 years
    I need something like a custom message reciever where I can execute my code that will start the application, but I am not sure is that possible yet with FCM
  • stevyhacker
    stevyhacker almost 8 years
    Just now I tried GCM and it works for my use case without problems, too bad FCM doesn't support this.
  • stevyhacker
    stevyhacker almost 8 years
    Thanks very much I will try this, well running the app on notification was just an example I just needed to be able to execute custom code on notification.
  • Diego Giorgini
    Diego Giorgini almost 8 years
    one more thing: the Firebase Web console can only send display-messages. To send data-messages you need to use the server-side API.
  • stevyhacker
    stevyhacker almost 8 years
    What do you mean server-side API, do I have to make a separate app server backend like for GCM?
  • Diego Giorgini
    Diego Giorgini almost 8 years
    yes. to send data-messages your still have to implement a separate app-server because the Firebase Web Console only sends display-messages. If you would like the console to support data-messages please send a feature-request: firebase.google.com/support/contact/bugs-features
  • fralbo
    fralbo over 7 years
    @stevyhacker For testing, you can use Google Advanced REST Client tool, and send your json message to https://fcm.googleapis.com/fcm/send. An example is here
  • Md. Sajedul Karim
    Md. Sajedul Karim over 7 years
    Thanks for your nice solution. Using your solution it is starting my TargetActivity but didn't getting extras in that activity. Have you any solution please?
  • ENSATE
    ENSATE about 7 years
    I don't understand why this answer get accepted, This answer is to specify which Activity should be launched when the user tap on the notification, the question is to "How to launch a specific Activity automatically without any user interaction?"
  • ENSATE
    ENSATE about 7 years
    This is not an answer to the question,we need to automatically launch activity without user interaction like tap notification.
  • blunden
    blunden over 6 years
    @DiegoGiorgini So using data-messages with FCM provides all of the same functionality as sending all the data as part of a Bundle did in GCM? I do that to be able to style the notifications properly (enriching them with profile picture, name, etc. from the user's contacts). Some posts suggest FCM is limited in that way but I hope that's simply incorrect. :)
  • fozua
    fozua over 5 years
    it does not work . when app is in the background, can not receive any message
  • thanhbinh84
    thanhbinh84 over 5 years
    Suppose you are done with step 2 and fail at step 3, what response when sending a post, if it is not 200, plz check the params you are using
  • Divyanshu Negi
    Divyanshu Negi over 5 years
    FirebaseMessagingService.onMessageReceived() this will not be invoked if the app is in the background and you have a data payload in the notification, tried and tested!
  • Zahirul Haque
    Zahirul Haque about 5 years
    I expected the answer how you guys launching the app automatically without user click on the notification in system tray.
  • Mark Lapasa
    Mark Lapasa almost 5 years
    @fralbo The link to your example is dead
  • Mr. Robot
    Mr. Robot over 4 years
    This doesn't actually answer the question.
  • Kato
    Kato over 3 years
    See the doc which explains where to put it (in the app manifest).
  • amoljdv06
    amoljdv06 over 3 years
    For all messages where onMessageReceived is provided, your service should handle any message within 20 seconds of receipt (10 seconds on Android Marshmallow). The time window may be shorter depending on OS delays incurred ahead of calling onMessageReceived. After that, various OS behaviors such as Android O's background execution limits may interfere with your ability to complete your work