Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Cloud Messaging - Android: click-action of notification when app is closed doesn't work

I'm using Firebase Cloud Messaging to deliver data messages to an application that i'm developing. According to FCM Documentation, when the app is in foreground:

A client app receives a data message in onMessageReceived() and can handle the key-value pairs accordingly.

and it works fine. When app is in background, the behavior is different:

the data payload can be retrieved in the Intent used to launch your activity.

and it doesn't seems to work pretty well. I'm using a "click_action" parameter in the notification JSON, where I specify the name of the intent filter used in the Android Manifest inside the "activity" tag that i want to open. For example, my notification could be:

{
    "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",
    "notification" : {
        "body" : "This is a test",
        "title" : "Test",
        "click_action" : "com.test.click"
    },
    "data" : {
        "key" : "data"
    }
}

And my manifest has this intent-filter, in the "MainActivity":

<intent-filter>
    <action android:name="com.test.click" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

When my app is in background and i launch the notification, everything seems to work well: I click the notification and the correct activity is displayed, and the data keys are in the "extras" of the intent received. The problem comes when my app is closed: when i tap on the notification, the app correctly starts and opens the activity with the "com.test.click" intent-filter, but if I try to send another notification, when I tap on it nothing happens, and background notifications doens't work anymore until I restart the app.

To be more clear: notifications work well while my app is in foreground or in background. If my app is closed, the first notification is handled correctly, but every other background notification doesn't work anymore until I restart the app: if i tap a notification, my app shows the last activity watched, as if I selected the app from the "Recent apps" menu. If i close and restart the app, the notifications return to work properly.

Is this a bug of the data-messages in Android, or a FCM issue? Is there a way to solve this issue?

I'm using a Nexus 5 API 23 for testing.

like image 398
Mattia Ruggiero Avatar asked Nov 21 '16 16:11

Mattia Ruggiero


People also ask

Do push notifications work when app is closed?

Let's start with Android. The Android OS is designed to listen for push messages and upon receiving one, wake up the appropriate Android app to handle the push message, regardless of whether the app is closed or not.

How do I get notifications when an app is closed Android?

Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.

How do I handle the Firebase notification when an app is in foreground?

Firebase notifications behave differently depending on the foreground/background state of the receiving app. If you want foregrounded apps to receive notification messages or data messages, you'll need to write code to handle the onMessageReceived callback.


1 Answers

I will try to describe how it's working on my case

Notification payload example:

{
"notification": {
    "body": "This is a test message",
    "title": "Message",
    "click_action" : "OPEN_ACTIVITY_1"
},
"data": {
    "key": "test key"

}

Manifest in the activity

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

When the app is in background or closed the FCM will create a "Notification message" and onClick it will open the right activity, then to handle the notification when the app is closed, call getIntent() in the onCreate() method

eg.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_hub);

    handleIntents(getIntent()); //for simplicity I'm passing the value forward


}

When the app is on the foreground I'm creating a custom notification in the method onMessageReceived on my FirebaseMessagingService.

eg.

    Intent intent = new Intent(this, HubActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("url", remoteMessage.getData().get("url"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("Message")
            .setContentText("This is a test message")
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

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

and to handle it appropriately in the activity I'm overriding the method onNewIntent(Intent intent).

eg.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    handleIntents(intent); //for simplicity I'm passing the value foward


}

so what I think you were missing is the onNewIntent(Intent intent) because this handles new intents when the activity is already created.

like image 69
Ruan_Lopes Avatar answered Sep 18 '22 06:09

Ruan_Lopes