17

I am using firebase to send notifications to my app. I want to save the notifications received on each device in a local database. The problem is, when the app is in the background and a notification is received, the method onMessageReceived() won't be called, but instead the notification would be added to the system tray as per documentation. The documentation also mentions the following for receiving a notification when the app is in background:

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, when I'm trying to access the extras in the intent, the keys of the notification are not found. My code in MainActivity.java:

if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Toast.makeText(this, "Key: " + key + " Value: " + value, Toast.LENGTH_LONG).show();
        }
    }

The notification we are sending from the server:

{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
  "body" : "great match!",
  "title" : "Portugal vs. Denmark",
  "icon" : "myicon"
  }
}

Anyone has an idea of how I can retrieve the values inside the notification?

AL.
  • 36,815
  • 10
  • 142
  • 281
riadrifai
  • 1,108
  • 2
  • 13
  • 26

4 Answers4

11

This is the intended behavior (as you've seen in the documentation). If you're using a notification-only message payload (which you are), onMessageReceived() will only be called if your app is in foreground, if not, the System Tray will be receiving it.

The data being referred to in (emphasis mine):

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.

is the data message payload (See Message Types).

You'll have to send a payload with both notification and data. Like so:

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "notification" : {
    "body" : "great match!",
    "title" : "Portugal vs. Denmark",
    "icon" : "myicon"
    },
  "data": {
    "body" : "great match!",
    "title" : "Portugal vs. Denmark",
    "icon" : "myicon"
  }
}

Also see my answer here.

Community
  • 1
  • 1
AL.
  • 36,815
  • 10
  • 142
  • 281
  • is there a way to handle the notification when the "notification"payload is there, this is because the system tray doesn't do a lot of things that are recommended, like grouping notifications, or in case of a messaging app, showing the avatar of the person that sends the notification – Andrey Solera Aug 15 '19 at 17:50
  • @Andrea I haven't tried overriding it. When I need custom handling for my notifications, I just send a `data`-*only* message payload, then handle it in `onMessageReceived()` – AL. Aug 16 '19 at 10:25
6

All you have to do is update your notification push format.

From:

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "notification" : {
    "body" : "great match!",
    "title" : "Portugal vs. Denmark",
    "icon" : "myicon"
   }
}

To

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    "body" : "great match!",
    "title" : "Portugal vs. Denmark",
    "icon" : "myicon"
   }
}

Explanation:

There is a firebase service running by your system which works for all app and handle all push notification if it contains the "notification" tag. but if contain the "data" tag only it just handover the task to the service created by the app where you can do anything.In your case show user notification and save it to the local db. For more you read here Documentation : Handle Messages.

AL.
  • 36,815
  • 10
  • 142
  • 281
  • But can you retrieve the notification's title using getBody() and get Title() message in case of a data payload? If it's a purely data payload, we need to create the notification in our onMessageReceived method correct? – Harsha Mar 30 '19 at 15:17
  • 1
    Yes, you can bind the json response to a Model class and can create getter and setter for each property. :) – Ashutosh Barthwal Mar 31 '19 at 17:20
1

It's not a simple or clean solution, but you could use a NotificationListenerService to receive a callback for each notification. A further limitation is that it supports only API 18 and above.

Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
0

Add this to manifest file

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