EddyVerbruggen / nativescript-plugin-firebase

:fire: NativeScript plugin for Firebase
https://firebase.google.com
MIT License
1.01k stars 444 forks source link

Behaviour of `onMessageReceivedCallback` on iOS - foreground vs background #1461

Open andrewbeng89 opened 4 years ago

andrewbeng89 commented 4 years ago

Hi @EddyVerbruggen thank you for your hard work in contributing and improving this awesome plugin! I have a couple of questions concerning the behaviour of the onMessageReceivedCallback on iOS, particularly in the difference when the app is running in the foreground vs. background.

Plugin Configuration

Current behaviour

  1. Given the configuration above, after a user has activated remote notifications (successful onPushTokenReceivedCallback), when a new APN notification is dispatched, onMessageReceivedCallback is called with { foreground: true } in the message.data payload. A system tray notification is also created.

  2. If the user tries to interact the the system tray notification after 1. (i.e. to open a detail view of the notification payload), no code is executed at all (presumably the code in onMessageReceivedCallback).

  3. However, if the user now closes and exits the app, all subsequent interactions with the system tray notifications behave as expected, with the onMessageReceivedCallback called. The message.data payload in this case now does not include the foreground property that was present in 1.

Is the behaviour in steps 1. and 2. something that is expected given my current configuration? Is there a possible way to configure the plugin to ensure that the actions in step 3. occur consistently without having to first close and exit the app (this is the actual feature requirements for the app)?

Is there anything else I'm missing here? Thanks in advance, and I'm looking forward to hear your thoughts in this issue 🙂

EddyVerbruggen commented 4 years ago

Thanks for the question.

Can you share your package.json and firebase.nativescript.json with me? Because I can't entirely reproduce this behaviour; with non-Firebase messaging (the demo-push app in this repo) I get a foreground notification, but no tray notification is created.

Maybe please also share the CURL command or just the payload you use to send a notification.

andrewbeng89 commented 4 years ago

@EddyVerbruggen thanks for looking into this issue. Here is the link to the package.json and firebase.nativescript.json I'm currently using in my project. Additionally, I have also shared the file containing onMessageReceivedCallback and registerForPushNotifications for reference (settings.ts). I'm using nativescript-vue for this project.

These are examples of the payload received in onMessageReveivedCallback:

Please let me know if it would be helpful to provide TestFlight access to understand the behaviour hands-on.

dereekb commented 4 years ago

I'm experiencing similar behavior in my app, although 2 for @andrewbeng89 is being handled by the LocalNotifications instead of not appearing.

My registration code for both looks something like this:

 ...

      firebase.registerForPushNotifications({
        showNotifications: false,
        showNotificationsWhenInForeground: false,
        onPushTokenReceivedCallback: (token) => {
          this._token.next(token);
        },
        onMessageReceivedCallback: (message: Message) => {
          console.log(`Received Message: ` + JSON.stringify(message));
          ...
        }
      }).then((x) => {
        return LocalNotifications.addOnMessageReceivedCallback((notification: ReceivedNotification) => {
          console.log(`Local Notification Tapped: ` + JSON.stringify(notification));
        ...
     }});

...

When a user receives a notification in the background after tabbing away from the app, I see this in the debug console:

CONSOLE LOG file:///src/app/shared/notification/notification.service.ts:268:22: Received Message: {"gcm.message_id":"1578780746971945","code":"pingmessage.new","google.c.a.e":"1","ping":"5731437370146816","title":"New Ping Message","body":"You recieved a ping message.","foreground":false,"data":{"gcm.message_id":"1578780746971945","code":"pingmessage.new","google.c.a.e":"1","ping":"5731437370146816","aps":{"alert":{"title":"New Ping Message","body":"You recieved a ping message."},"content-available":1},"title":"New Ping Message","body":"You recieved a ping message.","foreground":false}} `

So the remote notification is received by the app even though it is in the background, then processes it.

The notification still shows up in the Notification Center and remains there. Once I click that notification, the LocalNotifications code is then triggered and this is logged:

CONSOLE LOG file:///src/app/shared/notification/notification.service.ts:289:22: Local Notification Tapped: {"id":null,"title":"New Ping Message","body":"You recieved a ping message.","foreground":false,"event":"default"}

The issue in my case is that the data of the original notification is no longer available, and there isn't an identifier that ties it to the previously received notification.

When I disable the LocalNotifications registration I then have the same issue as @andrewbeng89 where no piece of code interacts with notifications that were "already processed" while the app was in the background.

Right now I'm trying to figure out how to remedy this issue where I can have push notification data be available when the user clicks on them in this situation.

dereekb commented 4 years ago

While testing on iOS just now I decided to change the configuration for "showNotifications" to true instead of false to see what would happen and now I get the desired behavior.

My new configuration:


      firebase.registerForPushNotifications({
        // Do not show notifications in foreground. Only recieve them to allow the rest of the app to use.
        showNotifications: true,
        showNotificationsWhenInForeground: false,

When the app is in the background:

CONSOLE LOG file:///src/app/shared/notification/notification.service.ts:268:22: Received Message: {"gcm.message_id":"1578795270627055","code":"pingmessage.new","google.c.a.e":"1","ping":"5731437370146816","title":"New Ping Message","body":"You recieved a ping message.","foreground":false,"data":{"gcm.message_id":"1578795270627055","code":"pingmessage.new","google.c.a.e":"1","ping":"5731437370146816","aps":{"alert":{"title":"New Ping Message","body":"You recieved a ping message."},"content-available":1},"title":"New Ping Message","body":"You recieved a ping message.","foreground":false}}

When the notification is clicked:

CONSOLE LOG file:///src/app/shared/notification/notification.service.ts:268:22: Received Message: {"code":"pingmessage.new","gcm.message_id":"1578795270627055","ping":"5731437370146816","google.c.a.e":"1","title":"New Ping Message","body":"You recieved a ping message.","data":{"code":"pingmessage.new","gcm.message_id":"1578795270627055","ping":"5731437370146816","google.c.a.e":"1","aps":{"alert":{"title":"New Ping Message","body":"You recieved a ping message."},"content-available":1},"title":"New Ping Message","body":"You recieved a ping message."},"notificationTapped":true,"foreground":false}

Both callbacks go to the Firebase onMessageRecieved and none go to the LocalNotification received callback, as expected/desired.

Is this supposed to be the intended effects of showNotifications? If I hadn't played with it I'm not sure I would have figured that out, as the documentation seems to imply that having that set to true will show notifications, where actually showNotificationsInForeground seems to control whether or not notifications actually appear when the app is in the foreground.