Firebase onMessageReceived not called when app is in the background
Asked Answered
B

4

15

I am using Firebase for our messaging service in our Android app. I have researched Firebase quite a bit and I understand that whether the app if running in the foreground or now will change the type of data received in the onMessageReceived method.

What I am trying to accomplish is to parse the incoming data from the Remotemessage and do something different with it depending on custom tag. IE, if the Data Map contains a field called, "My_Custom_Tag", I want to completely override the standard firebase message that pops up and write a custom one.

The problem is, when the app is running in the background, any code I put into the onMessageReceived never gets triggered. It works just fine when the app is running in the foreground, but will not detect/ receive anything if the app is in the background.

Here is some sample code below:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

    Map<String, String> aMap = remoteMessage.getData();
    //Custom object here for easier parsing
    PushNotificationsPojo pojo = this.convertResponseToPojo(aMap);

    if(pojo == null){
        passToFirebase(remoteMessage);
        return;
    }

    if(pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_CHAT_MESSAGE)) {
        createCustomNotification1(pojo);

    } else if (pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_SOME_OTHER_MESSAGE)){
        createCustomNotification2(pojo);

    } else if (pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_STUFF_AND_WHATNOT)) {
        createCustomNotification3(pojo);

    } else {
        passToFirebase(remoteMessage);
    }
}

My question is, how do I go about editing MyFirebaseMessagingService so that I can check the incoming data, determine tag info, and decide to either pass it on to firebase for so it can use the standard handling or not pass it to firebase and write my own custom display notification all while my app is running in the background?

Thanks all!

PS, any chance the Firebase-Dungeon-Master Frank van Puffelen has a thought?

Becka answered 28/10, 2016 at 18:37 Comment(4)
What type of payloads do the FCM Messages you send contain? Notification, data or both of them?Linet
Both, for the most part. Since it is cross-platform, IOS needs me to send the notification object, but most of our data is from the Data object.Becka
Omg! What does background meean here? Does it mean when the app is not active OR the App is closed?Brat
This is referring to the app is actually closed and out of memory.Becka
L
44

Remove the notification payload from your FCM messages in order to have the data payload delivered to the onMessageReceived method.

Read this and this carefully.

When your app is in the background, data payload delivered to the onMessageReceived method only if there is no notification payload. (Mark the words)

In case both payloads exist then system automatically handles the notification part (system tray) and your app gets the data payload in the extras of the intent of launcher Activity (after the user tap on the notification).

In order to be able to serve both platforms successfully, Android and iOS, you may have to send different FCM messages according to client's OS.

Linet answered 28/10, 2016 at 19:22 Comment(3)
@Linet But, how to remove notification when using Cloud Messaging on Firebase ? Notification Text must be input ?Landgraviate
What does background mean? App closed or app inactive???Brat
In the context of my question, in the background means the app is completely closed and not in memory. This answer though covers all 3 states of in the foreground, background (in memory), and background (not in memory).Becka
N
11

Guyz Listen carefully, I gone through many links and finally found solution here.

  1. When app is background onMessageReceived method should call

This payload will works...

{
  "data":{
    "title": "hello",
    "body": "this is body"
  },
  "to": "c5iuJ7iDnoc:APA91bG6j2c5tiQ3rVR9tBdrCTfDQYxkPwLuNFWzRuGHrBpWiOajR-DKef9EZEEVKA-kUBfXVcqHT-mClYfad06R_rBjhRZFKVdBL7_joXE5hFEwR45Qk8wgQdia2b-LmjI1IheFGZS8"
}

This payload will not work...

{
  "notification":{
    "title": "hello",
    "body": "this is body"
  },
  "to": "c5iuJ7iDnoc:APA91bG6j2c5tiQ3rVR9tBdrCTfDQYxkPwLuNFWzRuGHrBpWiOajR-DKef9EZEEVKA-kUBfXVcqHT-mClYfad06R_rBjhRZFKVdBL7_joXE5hFEwR45Qk8wgQdia2b-LmjI1IheFGZS8"
}

Because when the load contains "notification" onMessageReceived will not call

Nonary answered 16/8, 2017 at 11:59 Comment(5)
Appreciate the code samples as they show what the other answers were explaining, but it is not that the other payload will not work, just that it will be handled by the Firebase service and not handled by custom code.Becka
Hello, can u help me out when the app is in background I am receiving two notifications handled by system tray & it is working foreground receiving one notification. How can fix this?Nonary
sssvrock, that happens when you are getting payloads that include both notification and data (IE, for both IOS and Android). To fix that problem, distinguish between the two types. See my question here for more info: #45286702Becka
@Becka What Firebase Service? The one in the cloud or the Google Play Services on the phone????Brat
This is referring to the client-side one on the device. For more info, see this linkBecka
C
3

In this post , answer of Koot might be your solution. He said "I had the same problem. It is easier to use the 'data message' instead of the 'notification'. The data message always load the class onMessageReceived."

my solution is as per his advice

{
  "condition": "'reader' in topics",

  "data": {
    "title":"Please Check",
    "message": "This is a Firebase Cloud Messaging Topic Message 5!"
   }
}
Claudianus answered 4/1, 2017 at 18:36 Comment(0)
W
1

Pretty sure, you already know the behavior in Android that when using both notification and data payload, the Android system catches what's in the notification and the data payload is included in the intent when it's tapped.

AFAIK, this is the only way that it goes (as per mentioned by @ArthurThompson here) and if you really want to make sure that onMessageReceived() is always called, you have to only use data payload (as mentioned by @DiegoGiorgini here) However, I've looked around, maybe there's another way.

I haven't tried it out myself, but have you considered checking which notifications are in the Status Bar, then if your notification exists (not entirely sure if you can actually identify which one is a notification for your app though), call the methods you usually call inside onMessageReceived().

One approach that you can also do is to detect if the device(s) you'll be sending the message to is an Android device in you app server, then send only a data payload.

Wheelsman answered 28/10, 2016 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.