React-native-fcm: FCM.on(...) function not call when I open notification from notification tray in background mode.

Created on 18 Sep 2017  路  43Comments  路  Source: evollu/react-native-fcm

Hi.
I'm using react native fcm to receive remote notification from my server(have payload data), and when I call FCM.on(...) function in foreground mode, it's working correctly. But when I close app, after click notification, it's just open app and don't show payload data. Can I get payload data when app closed?
Thank.

question

Most helpful comment

for your FCM.on not launching issue. it is possible that your app Activity is closed by the time you click on banner. check getIntialNotification() and see if it contains the notification data.

for your "action":"android.intent.action.MAIN" issue. that is expected. The android version of click on banner detection is done though intent, which means your regular intent will be included as well. That's expected and you can filter it out yourself.

All 43 comments

it is android or ios? what is your payload?
don't show payload data are you using Alert?

I'm also having the same issue, the FCM.on(...) function is only called when app is in foreground, it never triggers when it is in the background and I click the notification and the app is called to foreground.

I'm currently testing this with the Android Emulator, Nexus 6, Google APIs Intel Atom (x86_64), google_apis [Google APIs] (API level 23).

I receive this payload correctly when in foreground:

{
    collapse_key: "customkey",
    event: "document.create",
    fcm: {
        action: null,
        body: "New data received",
        color: null,
        icon: null,
        tag: null,
        title: "New Document"
    },
    from: "298328200808",
    google.message_id: "0:1505750690123439%e3881134e3881234",
    google.sent_time: 1505750690140
}
FCM.on(FCMEvent.Notification, async (notif) => {
        console.log(notif); // -> this only gets triggered when in foreground !!!

        // there are two parts of notif. notif.notification contains the notification payload, notif.data contains data payload
        if(notif.local_notification) {
            //TODO: NOT CURRENTLY WORKING -> react-native-fcm
            //this is a local notification
            console.log("local notification recieved!");
        }
        if(notif.opened_from_tray){
            //TODO: NOT CURRENTLY WORKING -> react-native-fcm
            //app is open/resumed because user clicked banner
            console.log("notification opened/tray recieved!");
        }
        // const notification = parseNotificationData(notif);
        // showLocalNotification(notification);
});

Do I need to send additional data in the payload in order to trigger this event when app is in the background and I click the notification to open the app ???

Also tested on a live android but I'm having the same issue.

If you can debug Android, make sure MessagingService.java's onMessageReceived is called correctly

@evollu at the moment I'm a bit tied up with work, haven't had time to debug this! Let me know if somebody else is able to reproduce this, or maybe @xuho could give us some more feedback on his side!

@evollu: I'm debug on Android device, both virtual device and real device but i'm having the same issue. FCM.on(...) is not trigger. I show payload data by console.log.

@xuho did you add breakpoint in java code when you debug?

I dont think it's 100% the same problem but using version 9.3.0 and following the example in the ReadMe, I can actually get the call to FCM.on in both background and foreground modes. The problem is that I can't get
if (notif.opened_from_tray) {
to work in background mode. When the app is in foreground I get all the relevant data including the key "opened_from_tray". When in background, I get mostly data sent from the server and when I clicked on the notification, the app opens but can't get any info about being opened from tray or not.

@ksegla what OS?

@evollu
Android: 7.0 (on a Samsung S8) and 5.1.1 (on a Samsung S6)
RN: 0.43.2

P.S: Really happy to have your ear. This issue is pretty much one of the last things I have to iron out before releasing my app. Thanks for the great work.

@ksegla what's your payload?

@evollu
Case 1: Remote
{ "to":token, "data": { badge: 1, number: 1, "custom_notification": { "body": msg, "title": user.firstName, "priority":"high", "show_in_foreground": true, "picture": user.picture } }}
I receive:
{ number: 1, "custom_notification": { "body": msg, "title": user.firstName, "priority":"high", "show_in_foreground": true, "picture": user.picture } collapse_key: null, fcm: {}, from: "...", badge: 1, google.message_id: "...", google.sent_time: .... }

When I'm already in the app (foreground) and click on the notification banner, I get "opened_from_tray":1 in the notif. Nothing if I clicked on the banner with app in background.

Case 2: Local Notification
Same thing. Unsurprising since I'm using custom_notification for the remote case.

I can't reproduce it. notice that when you click a notification created by custom_notification, you will only get what's inside custom_notification. so your callback data will be just
{ "body": msg, "title": user.firstName, "priority":"high", "show_in_foreground": true, "picture": user.picture, "opened_from_tray":1 }

also I notice you have badge and number outside of custom_notification, they will be ignored. put them inside custom_notification if you want SDK to handle it

@evollu
OK. I'll dig some more and see if I can come up with a solution or better findings for you to look at.
PS: In my example, I'm having the expected behavior (1 is super-imposed to the app icon) only when "badge" is in data, not when it's in custom_notification (nothing added).

@ksegla you are right about the badge

just want to confirm, when you say background you are not killing the app right?

No
Just putting it in background: switching apps or going to "Android homepage".

@evollu
As a workaround, is there a way to customise the handling of clicks from the banner through the settings of action_click? (So far I've been using Hello as a click action. Didn't adapt from the example. It was not too clear from the docs how to set different actions).
That way, I would always have a landing page for clicks on the banner. And would know if I should then use data received from the notifications (and saved) to decide which screen to show.
Thanks

that doesn't help telling you if user clicked the banner. What it does is changing intent of current app.

Did you set "singleTop" as readme states?
Also if you can debug Android like using Android Studio, try put breakpoint at https://github.com/evollu/react-native-fcm/blob/master/android/src/main/java/com/evollu/react/fcm/FIRMessagingModule.java#L300
This line should be called when you click banner

Yes, it is "singleTop". I plugged Android Studio and could examine the logs. No particular insights. As for the breakpoint, unless I'm mistaken, it would require taking the java code from the android folder and making it a project in Android Studio, then generating a new apk that would replace the current apk on my devices. Will see how to proceed with that later. (Edit: I will first try putting an Alert in your Java source code. Less powerful debugging but a reasonable start, I think )

Thinking about it, I think I actually have the same issue as the OP. FCM.on(..) does launch when the notification is received but when it comes to clicking on the notification banner, FCM.on(..) only launches when I'm already in-app (foreground).

Additionnally, when I click on the app icon (not the banner), FCM.on(..) launches every time and notif gives me {"opened_from_tray":1, "fcm":{"action":"android.intent.action.MAIN"},"profile":0 } . Every time, except when I had closed the app or quit it using the Android Back button.

PS: @evollu I hate to do this but this has been a crucial issue/question for me (for 8 months now). It's about whether it's possible to customise the notification text (to handle special characters 茅 脿 etc. from languages like French)
https://github.com/evollu/react-native-fcm/issues/271

for your FCM.on not launching issue. it is possible that your app Activity is closed by the time you click on banner. check getIntialNotification() and see if it contains the notification data.

for your "action":"android.intent.action.MAIN" issue. that is expected. The android version of click on banner detection is done though intent, which means your regular intent will be included as well. That's expected and you can filter it out yourself.

@evollu
YES!!! Putting FCM.getInitialNotification().then(notif=>alert("INITIAL:\n" + JSON.stringify(notif))); in the componentDidMount() of my main component works!!
In tandem with FCM.on() placed outside the component lifecycle (the code from the readme). Like, if FCM.on doesn't launch, FCM.getInitialNotification() in componentDidMount() does (and in some cases vice versa). YASSS!! :-D

Gotta iron out a few kinks but it's good enough as a workaround for me. Thanks @evollu for listening/giving feedback through the day and providing workarounds for two very important issues for my app. You rock! 馃

awesome!
However I want to get idea of what exactly is going on so I can add it to readme.
You closed the app by clicking back button and you placed FCM.on outside of component lifecycle. but the on callback still doesn't trigger and the notification goes into FCM.getInitialNotification()?

BTW, I've updated version to filter out "android.intent.action.MAIN"

OK. From the start, I've been using your sample code in the readme and I was trying to catch the notif in the first FCM.on (the one that is outside the component lifecycle), especially for cases when I clicked on a notification.

When I clicked on notification banners, FCM.on would be triggered only when the app was already foreground.
When I clicked on the app icon, FCM.on would be triggered unless I had quit the app by a./ closing it (X button) or b./ using the Back Button (on the first screen, when it means close the app).

The only thing I did differently is that, based on your suggestion, I placed FCM.getInitialNotification().then(notif=>{handle notif...}; inside the componentDidMount.
Now either the FCM.on gets triggered or the getInitialNotification inside the component lifecycle gets the notif. I can't say with certainty yet if it's always mutually exclusive.

As you say, it's very possible that it's a matter of being in the right time window to catch the FCM.on. In any case, getInitialNotification is there to get the notification. I'd say the readme could may be highlight getInitialNotification a bit more. I went through it again and the info was pretty much there, just relatively easy to overlook.

PS: In your sample code, there is also a second FCM.on in the componentDidMount but I was not using it and as a matter of fact, it didn't seem to improve the situation when I experimented with it. It wouldn't trigger. EDIT: I mean it wouldn't trigger if the first FCM.on didn't.

cool. I'm not android expert but I did notice sometime the activity gets recreated when app goes background, which will lead to the notification going to initial notif. will update readme regarding this issue.

馃憤
yeah, Android is tricky. And the newer versions seem to be even more pro-active about killing background apps. anyway, thanks again!

@ksegla I've just try your solution and I've follow the readme too but I still can't get this work. Now I'm using react-native-firebase that works fine but I would lit to use this instead for some features

@bm-software what is your issue?

FCM.getInitialNotification() is the answer I'm looking for. Thank @evollu

cool readme updated regarding this
@bm-software i'm closing this issue as it seems to be solved in general. You can keep posing in the thread though

@evollu When I open the notification from try, the on method is not called and the FCM.getInitialNotification() method return a null object (always).
Moreover i if I put this last method in componentDidMount it won't be called if I "close" the app with the home button.

@bm-software can you add breakpoint https://github.com/evollu/react-native-fcm/blob/master/android/src/main/java/com/evollu/react/fcm/FIRMessagingModule.java#L301 and se if it gets trigger when you click notification?

@bm-software
Sorry that it's not working out for you. Just in case, which Android version are you experimenting on? (On my side, I can confirm that FCM.getInitialNotification is doing the job on 4.4, 5.1. and 7.0. No reason to think the behavior is version-dependent but you never know...)

@evollu I will try to add a breakpoint there today and I'll let you know.
@ksegla I'm testing on Android 8.0 (Nexus 5X)

@bm-software
Just in case, there seems to be some kind of inertia when an Android app (at least mine) is launched. So while I was able to catch the initial notification immediately, I had to use this
setTimeout(() => {handleNotification(notif.data)},1000);
to correctly access and alter my redux store within the handleNotification function. So you may want to try something like that to check if your problem is not the result of some kind of delay/slow start of the app. (I know setTimeOut is an anti-pattern without mixins but you can try it for a quick check).

I'm receiving the notification when the app is on background but I still having problem to get the notif

setTimeout(() => {
  FCM.getInitialNotification().then((notif) => {
    console.log(`1. FCM.on:`.repeat(100), notif) // work only on foreground 
  })
  FCM.on(FCMEvent.Notification, async (notif) => {
    console.log(`2. FCM.on:`.repeat(100), notif) // work only on foreground 
  })
}, 1000)

Testing on Android Nexus API (simulator)

"react": "16.0.0-alpha.12",
"react-native": "^0.48.4",
"react-native-fcm": "^9.5.0",

@rochapablo are you sending notification rather than data in payload? Firebase eats up the message when you are in background in Android. If you want to handle even when app is in background, use data payload only

Thank you @evollu! I saw you guys talking about this but I haven't notice that was in my backend api. Indeed removing notification and adding data did work.

return fcm.send({
    to: '...',
    data: { title: ..., body: ... }
    /* notification: { ... } */
  })

Hi,

I'm seeing something similar, but not sure if it is exactly the same.. In some cases, when i click on the notification toast, i get the notification properly in my app in the FCM.on callback that i have as follows:

    FCM.on(FCMEvent.Notification, async (notif) => {
        logger.log("received notification: " + JSON.stringify(notif))
        handleNotification(notif)  // my code to handle the notification
    }

However, in one particular case, the above code doesn't get invoked. This is when I wait for a long time (say, 15+ minutes) before I click/tap on the notification toast. I think Android puts the app to sleep after that much time?

I am also already checking for FCM.getInitialNotification as follows.. (the code below is invoked from one of my componentDidMount methods)..

    FCM.getInitialNotification().then(notif => {
        if(notif){
            logger.log('Got initial notificaton: ' + JSON.stringify(notif))
            NotificationUtil.handleNotification(notif)
        }
    }

I do get something in the above block (initial notification), but its kind of empty. the log statement above is:

Got initial notificaton: {"opened_from_tray":1,"fcm":{"action":null}}

And this happens only when I wait for a while before i click/tap on the notification toast (not sure if some folks here are calling that a 'banner' - which is available when you swipe/pull down from the top of the phone screen)..

If the app is just minimized, and i tap on the notification toast in a couple of minutes, everything works fine - my FCM.on callback gets invoked, and i get the complete notification data as expected.. here's one log for the success case:

received notification: {"fcm":{"action":"my_test_action"},"show_in_foreground":true,"data.foo":"bar","sound":"default","opened_from_tray":1,"click_action":"my_test_action","priority":"high","id":"my_notif_id","body":"test notif body","title":"test notif title","icon":"ic_launcher","local_notification":true}

@evollu - do you know what could be causing this?

Thanks
Amit

Android 7.1.1 emulator (same behavior on many other versions)..
"react": "^16.2.0",
"react-native": "^0.51.0",
"react-native-fcm": "^11.3.1",

@bhosle-git is FCM.on(FCMEvent.Notification outside of component lifecycle?

it is called from my index.android.js (i register the listeners when my app launches)..
what happens to these when the app goes to 'sleep'?

btw, from some earlier discussions, i was expecting the notification to be available via FCM.getInitialNotification(..), and that does seem to get something, but not the full content (in this scenario where i click on the toast after 15-20 mins)..

Got initial notificaton: {"opened_from_tray":1,"fcm":{"action":null}}

quick update here..

i realized that we had upgraded the react-native-fcm version recently (11.3.1).. but when i rolled back to an earlier one (10.0.3), things work as expected!

(double checked a few times rolling back/forward on these two versions, and that's what it looks like - regression in some version after 10.0.3)

Going to roll with 10.0.3 for now..

Can any one help me for that if i will put this :- FCM.getInitialNotification().then(notification => {
console.log('initial notification', notification);
FCM.getInitialNotification().then(notification=>alert("INITIAL:\n" + JSON.stringify(notification)));
### // called when we open app
});

FCM.on(FCMEvent.Notification, async notif => {
### //Called each time when either you click or not
console.log('notification payload FCMEvent===>', notif);

});

out side the class. It was call each time when app is open
I want that when notif. is come and if i click on notification than only it will called and alert on my screen
For Ex( i want when some one is sending me msg. than notification is come and when i click on notf. it will redirect to the chat screen directly not on a home page of app so what should i do for that can any one help me hope you understand my concept )

Was this page helpful?
0 / 5 - 0 ratings