andrehtissot / cordova-plugin-fcm-with-dependecy-updated

Google FCM Push Notifications Cordova Plugin
MIT License
210 stars 273 forks source link

When the Application is in foreground, notification data is NOT received in the JavaScript callback on Android #251

Open vigamage opened 3 years ago

vigamage commented 3 years ago

Describe the bug fcm.onNotification() is called only when the user taps on the push notification. Therefore, there is no way that the notification data can be retrieved inside the callback when the push is received while the app is in foreground.

Even if the documentation says the notification data is received in the JavaScript callback when the app is in foreground, it does not happen in Ionic 5 app. When the app is in the background, it works fine.

To Reproduce Subscribe to the notifications by placing fcm.onNotification() inside constructor.

Expected behavior Notification data should be received in the JavaScript callback without notification bar message.

Environment

Package.json

"dependencies": {
    "@admob-plus/ionic": "^1.1.9",
    "@angular/animations": "^10.2.2",
    "@angular/common": "~10.2.5",
    "@angular/core": "~10.2.5",
    "@angular/fire": "^6.1.4",
    "@angular/forms": "~10.2.5",
    "@angular/platform-browser": "~10.2.5",
    "@angular/platform-browser-dynamic": "~10.2.5",
    "@angular/router": "~10.2.5",
    "@capacitor/android": "^1.5.3",
    "@capacitor/cli": "^1.5.3",
    "@capacitor/core": "^1.5.3",
    "@ionic-native/core": "^5.28.0",
    "@ionic-native/fcm": "^5.32.1",
    "@ionic-native/splash-screen": "^5.28.0",
    "@ionic-native/status-bar": "^5.28.0",
    "@ionic/angular": "^5.3.2",
    "@ngx-translate/core": "^12.1.2",
    "@ngx-translate/http-loader": "^4.0.0",
    "admob-plus-cordova": "^1.8.0",
    "angular-font-awesome": "^3.1.2",
    "bootstrap": "^4.5.2",
    "capacitor-resources": "^2.0.4",
    "cordova-admob-sdk": "^0.24.1",
    "cordova-plugin-fcm-with-dependecy-updated": "^7.8.0",
    "cordova-promise-polyfill": "0.0.2",
    "core-js": "^2.5.4",
    "firebase": "^7.20.0",
    "font-awesome": "^4.7.0",
    "jetifier": "^1.6.6",
    "jquery": "^3.5.1",
    "lodash": "^4.17.20",
    "promise-polyfill": "^8.1.3",
    "rxjs": "^6.5.5",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  }
sethamzcorvete commented 3 years ago

I think u can use local notification plugin

DavidAMcIntosh commented 3 years ago

I think u can use local notification plugin

yes, this is the way. you can use take the data payload and make your own notifications to show. https://github.com/katzer/cordova-plugin-local-notifications

vigamage commented 3 years ago

Any particular reason why the documentation says "the notification data is received in the JavaScript callback when the app is in foreground"?

DavidAMcIntosh commented 3 years ago

That's just generally how push notifications work. Ever been in Whatsapp and noticed that if you get a new message while the app is open, you don't get it in the notification tray? It simply updates the UI. Same applies here. You can read the new notification payload in the background, since the user is already in your app, and present in an unobtrusive way.

For my app, if the app is in the foreground, the user simply gets a modal that shows a preview of the notification and can choose to view or ignore it (since it is an alert about account activity, etc.).

vigamage commented 3 years ago

Doesn't the "javascript callback" in the documentation refer to the callback of onNotification function ?

DavidAMcIntosh commented 3 years ago

It does. Can you share a snippet of the code, maybe? Something like this should definitely work:

this.fcm.onNotification().subscribe(data => { if (data.wasTapped) { // app was not in foreground, and user had to "tap" notification } else { // app was in foreground, so the OS did NOT show the notification. there was nothing to tap, so you can choose what to do with // the data here. } });

vigamage commented 3 years ago

in my constructor

constructor(private fcm: FCM)  {
    this.initializeApp();
}

initializeApp function

initializeApp() {
    this.platform.ready().then(async () => {
      console.log('PLATFORM READY')
      ................
      ................
      this.setupFCM();

    });
  }

setupFCM function

private async setupFCM() {

    console.log('Subscribing to new notifications');
    this.fcm.onNotification().subscribe((payload) => {
      if (payload.wasTapped) {
        console.log("Received in background -> ", JSON.stringify(payload));
      } else {
        console.log("Received in foreground -> ", JSON.stringify(payload));
      }
      this.pushPayload = payload;
      console.log('onNotification received event with: ', payload);
    });

}

now in my case, when the app is in foreground, above else block does not print to console.

vigamage commented 3 years ago

@DavidAMcIntosh Do I need anything specific inside my data payload in the push message in order for above subscription to work when the app is in foreground?

{
"to":"/topics/general",
 "notification" : {
  "sound" : "default",
  "body" :  "test body 14",
  "title" : "Test Title",
  "content_available" : true,
  "click_action":"FCM_PLUGIN_ACTIVITY",
  "priority" : "high"
 },
 "data" : {
  "sound" : "default",
  "body" :  "test body",
  "title" : "test title",
  "content_available" : true,
  "priority" : "high",
  "dataObj" : {
      "type": "EVENT_DETAILS",
      "redirectObj": {
          "to": "/event-details",
          "params": ["A", "B"]
      }
  }
 }
}
DavidAMcIntosh commented 3 years ago

I only see a few differences between your object and mine. This is how I structure mine:

export interface FcmRequest { notification: { title: string; body: string; sound: string; click_action: string; icon: string; }, to: string; priority: string; data: { message: string; username: string; notificationId: number; action: string; } };

I noticed you repeat some of the notification fields inside your "data" object, then you have an inner "dataObj" inside that data object, which to me doesn't seem necessary but i'm not certain it would really affect the notification.

In my app, I subscribe to "all" messages, as I'm not sending to any specific topic, but just in case, are you subscribing to the "/topics/general" in your Ionic app?

this.fcm.subscribeToTopic('all'); <- works for me

Hope this helps!

DavidAMcIntosh commented 3 years ago

This is an example of how I would populate mine:

fcmRequest.notification = {
  title:"My App Alert",
  body: fcmAppRequest.shortMessage, // just a string
  sound: "default",
  click_action: "FCM_PLUGIN_ACTIVITY",
  icon: "fcm_push_icon"
}; 
fcmRequest.to = fcmAppRequest.firebaseToken;
fcmRequest.priority = "high";
fcmRequest.data = {
  message: fcmAppRequest.message,
  username: fcmAppRequest.username,
  notificationId: notificationId,
  action: fcmAppRequest.action
};