EddyVerbruggen / nativescript-plugin-firebase

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

onMessageReceivedCallback not called when the app is in background #323

Open manishmlv50 opened 7 years ago

manishmlv50 commented 7 years ago

I am getting notification when the app is in the background but when the notification is tapped the callback method is not called. It works fine when the app is terminated or when the app is active.

Please help.

the following is my package.json

{ "description": "Test", "license": "", "readme": "", "repository": "", "nativescript": { "id": "com.test.test", "tns-android": { "version": "2.5.0" } }, "dependencies": { "@angular/common": "2.4.5", "@angular/compiler": "2.4.5", "@angular/core": "2.4.5", "@angular/forms": "2.4.5", "@angular/http": "2.4.5", "@angular/platform-browser": "2.4.5", "@angular/platform-browser-dynamic": "2.4.5", "@angular/router": "3.4.5", "email-validator": "1.0.4", "moment": "2.17.0", "nativescript-angular": "1.4.0", "nativescript-audio": "^3.0.1", "nativescript-calendar": "^1.2.1", "nativescript-camera": "0.0.8", "nativescript-cardview": "^1.2.0", "nativescript-carousel": "^2.1.1", "nativescript-checkbox": "^1.2.2", "nativescript-drop-down": "^1.5.3", "nativescript-imagepicker": "^2.5.1", "nativescript-keyboardshowing": "^1.0.0", "nativescript-loading-indicator": "^2.2.2", "nativescript-local-notifications": "^1.2.1", "nativescript-plugin-firebase": "^3.10.0", "nativescript-screen-orientation": "1.0.2", "nativescript-telerik-ui": "^1.6.1", "nativescript-theme-core": "~1.0.2", "nativescript-timedatepicker": "1.1.0", "nativescript-toast": "1.4.5", "reflect-metadata": "~0.1.8", "rxjs": "~5.0.1", "tns-core-modules": "^2.5.1", "tns-platform-declarations": "2.4.4" }, "devDependencies": { "@angular/compiler-cli": "2.4.5", "@ngtools/webpack": "1.2.10", "babel-traverse": "6.8.0", "babel-types": "6.8.1", "babylon": "6.8.0", "copy-webpack-plugin": "~3.0.1", "extract-text-webpack-plugin": "~2.0.0-beta.4", "htmlparser2": "~3.9.2", "lazy": "1.0.11", "nativescript-css-loader": "~0.26.0", "nativescript-dev-android-snapshot": "^0..", "nativescript-dev-typescript": "^0.3.2", "nativescript-dev-webpack": "^0.3.6", "raw-loader": "~0.5.1", "resolve-url-loader": "~1.6.0", "tslint": "4.0.0", "typescript": "2.1.6", "webpack": "2.2.1", "webpack-sources": "~0.1.3", "zone.js": "~0.7.2" }, "scripts": { "tslint": "tslint \"app/*/.ts\"", "ns-bundle": "ns-bundle", "start-android-bundle": "npm run ns-bundle --android --start-app", "start-ios-bundle": "npm run ns-bundle --ios --start-app", "build-android-bundle": "npm run ns-bundle --android --build-app", "build-ios-bundle": "npm run ns-bundle --ios --build-app" } }

I am initialising the firebase in the app Component controller:

import { Component, NgZone } from "@angular/core"; import as firebase from "nativescript-plugin-firebase"; import { OneService } from "./modules/services/one.service"; import { RouterExtensions } from 'nativescript-angular/router'; import as LocalNotifications from "nativescript-local-notifications";

import { isAndroid } from 'platform'; import as Toast from 'nativescript-toast'; import as application from "application";

import { Page } from "ui/page";

declare var com: any;

@Component({ moduleId: module.id, selector: "my-app", template: '' }) export class AppComponent {

constructor( private _page : Page, private _oneService: OneService, private routerExtensions: RouterExtensions, private ngZone: NgZone ){ this._page.actionBarHidden = true; console.log("App Component is loaded"); console.log("Application launched on: "+ new Date());

this.initializeMethods();
firebase.init({
    persist: true,
    onMessageReceivedCallback: (message:any) => {
      console.log(JSON.stringify(message));

      if(message.foreground == false){
        console.log("Message received when app was closed");
      } else {
        console.log("Message received when inside the app");
        console.dump(message);
       }

    },
    onAuthStateChanged: (data) => {
        console.log(data.loggedIn ? "Logged in to firebase" : "Logged out from firebase");
        if (data.loggedIn) {

          var token = com.google.firebase.iid.FirebaseInstanceId.getInstance().getToken();
          console.log( token );
          this._oneService.userToken = token;
          firebase.addOnPushTokenReceivedCallback((token)=> {
            this._oneService.userToken = token;
            console.log("Firebase push token: " + token);
          });
        } else {
            console.log("No user found");
            // OneService.prototype.user = data.user.uid;
        }
    }

}).then(
    (instance) => {
        // console.log("firebase.init done");
    },
    (error) => {
        // console.log("firebase.init error: " + error);
    }
);

}

initializeMethods(){

LocalNotifications.requestPermission().then(
    function(granted) {
      console.log("granted");
    }
);

LocalNotifications.addOnMessageReceivedCallback((notification: any) => {
  console.dump(notification);
 }).then(function() {
    console.log("Listener added");
  });

}

showLocalNotification(message : any){ console.log("Showing local notification"); console.dump(message);

LocalNotifications.schedule([{
    id: messageId,
    title: message.title,
    body: message.body,
    smallIcon: 'res://icon',
    largeIcon: 'res://icon',
    sound : null
  }]).then(() => {
        console.log("Notification Scheduled");
      },(error)=> {
        console.log("doScheduleId5 error: " + error);
      }
  );

}

The following is my setting for the AppManifest:

<application
    android:name="com.tns.NativeScriptApplication"
    android:allowBackup="true"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:theme="@style/AppTheme">

    <activity
        android:name="com.tns.NativeScriptActivity"
        android:label="@string/title_activity_kimera"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:theme="@style/LaunchScreenTheme"
        android:screenOrientation="portrait"
        android:launchMode="singleTop">
        <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name="com.tns.ErrorReportActivity"/>

    <service android:name="org.nativescript.plugins.firebase.MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
    <service android:name="org.nativescript.plugins.firebase.MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>
</application>

The following is my code to send notification:

//Send notification to fcm publishMessageNotification(options){ console.log("Sending Push Notification"); console.dump(options); var notificationBody = "";

let notification : { 
      "body" ?: string, 
      "tag" ?: string, 
      "title" ?: string,
      "priority" ?: string
    } = {
      priority : "high"
    };
switch (options.conversationType) {
  case "direct-message":
    // notificationBody = "You have new direct messages";
    notification.body = "Has sent you a Private Message";
    notification.tag = options.groupKey
    notification.title = this._oneService.user.value.fname + ' ' + this._oneService.user.value.lname;
    break;

  case "private":
    // notificationBody = "You have new messages in "+ this.title;
    notification.body = "You have new messages in "+ options.conversationName;
    notification.tag = options.entityKey;
    notification.title = options.entityName;
    break;

  default:
    notification.body = "You have new messages in "+ options.entityName;
    notification.tag = options.entityKey;
    notification.title = options.entityName;
    break;
}

console.log(JSON.stringify({ 
    "to": "/topics/"+options.conversationKey, 
    "collapse_key" : options.entityKey,
    "data": { 
      "conversationId" : options.conversationKey,
      "userId" : options.userKey,
      "groupId" : options.groupKey,
      "entityId" : options.entityKey,
      "conversationType" : options.conversationType,
      "conversationName" : options.conversationName
    }, 
    "notification": notification
  }));
http.request({
  url: "https://fcm.googleapis.com/fcm/send",
  method: "POST",
  headers: { 
    "Content-Type": "application/json" ,
    "Authorization" : "key="+this.authToken
  },
  content: JSON.stringify({ 
    "to": "/topics/"+options.conversationKey, 
    "collapse_key" : options.entityKey,
    "data": { 
      "conversationId" : options.conversationKey,
      "userId" : options.userKey,
      "groupId" : options.groupKey,
      "entityId" : options.entityKey,
      "conversationType" : options.conversationType
    }, 
    "notification": notification
  })
}).then(function (response) {
  // push notification response
  console.log("Push Notification Response");
  console.dump(response);
}, function (e) {
    console.log("Error occurred " + e);
});

}

EddyVerbruggen commented 7 years ago

Which platform(s)?

manishmlv50 commented 7 years ago

Android. When the launchMode is set to singleTop in the AndroidManifest.xml

KingAndroid commented 7 years ago

same problem here too. here is my dev env. ios -> 10.3 xcode -> 8.3 osx -> 10.12.4 ns -> 2.5.3 plugin -> 3.10.0

app will receive push notification in foreground mode, but not in background mode & not run it worked on ios 10.2.1, but not work for now. I wonder it is system problem or plugin problem.

EddyVerbruggen commented 7 years ago

@KingAndroid is your situation also affected by launchMode as @manishmlv50 says?

KingAndroid commented 7 years ago

thanks for your message. as I mentioned above, I have meet issue on ios verison. could I get any resolution for this issue?

what I tried is as follow.

  1. provisioning -> it is ok due app works well at foreground.
  2. capability -> background mode & push notification enable on app info.plist.
  3. firebase Proxy disable on project info.plist.

But I did not resolve it. regards / zheng

jorgelcf commented 7 years ago

@Eddy This is the same as #297. When you set launchMode to singleTop (in my case to avoid Angular to start a new instance... bug?) then you have to get the extras from OnNewIntent(). See also this.

KingAndroid commented 7 years ago

@Eddy, thanks for your reply. Please read my comment again.

I faced this issue on # ios platform. FCM works well on forground mode, but not on background mode. Could i get any resolution for that?

Thanks

EddyVerbruggen commented 7 years ago

Please don't ping this @ Eddy guy, it's not my handle.

And @KingAndroid I think you're replying to @jorgelcf anyway. Also, why did you disable the Firebase proxy? It's not in the readme. Can you try again after that's been removed please.

KingAndroid commented 7 years ago

ok, @EddyVerbruggen I'll ask @jorgelcf about this issue. disable firebaseproxy, I have hinted from runtime logging. I've tried both case -> enable / disable and result were same. And, i am talking about ios, but this issue was marked android. Could you please give try for ios issue.

I appreciate your great support. Thanks

EddyVerbruggen commented 7 years ago

@KingAndroid This issue was created for a problem on Android, so it's labeled that way. You kind of hijacked it by throwing in your iOS problem.

I know about the log message, but please remove it.

KingAndroid commented 7 years ago

Because, nativescript is cross platform, and this plugin is also using for both platform. Even though issue was labeled as android, but it is same problem. it was jut my thought, so I was commented on this issue. if so, do i need to create new issue like this labeled ios?

EddyVerbruggen commented 7 years ago

It may be the same problem, but not the same solution, and not fixed at the same time in the same release. So it's easier to have focused issues.

If my suggestion doesn't work for you then by all means open a new issue, but also include a demo project to recreate it with. The entire source, not just a snippet please.

KingAndroid commented 7 years ago

ok, @EddyVerbruggen thanks for your suggest. I'll make sample to attach on new issue.

manishmlv50 commented 7 years ago

According to the docs, When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload. 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. This is why the onMessageReceived callback is not called.

We can try to get the intent extras on the onResume event of the activity and check if it has the notification data and then process it

priyangamani commented 7 years ago

Push notification works well on foreground , but not in the background mode.OnMessageReceivedCallback Does not triggered in background mode....

simonettoa commented 7 years ago

Hi @manishmlv50 and @priyangamani , I'm having trouble to solve this issue in android (ios works fine). I set the singleTask in the AndroidManifest.xml file. I had the applicationOn with resumeEvent set.

If I send a notification (from the terminal using CURL command) and the app is in foreground it takes care of it from the 'addOnMessageReceivedCallback' function, in background the notification arrives but when I click on it I don't have any Extras from the getExtras function.

Here what I've got from the (args.android).getIntent() function:

intent value -> Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.nativescript.TruckMe/com.tns.NativeScriptActivity }

And this is the resume function that I've put in the app.component.ts file:

` applicationOn(resumeEvent, function(args: ApplicationEventData) { if (args.android) { // For Android applications, args.android is an android activity class. console.log("***** resumeEvent Activity: " + args.android);

    let intent = (args.android).getIntent();
    console.log("intent value -> " + intent);

    let extras = intent.getExtras();
    if(extras) {
        let extras = args.android.getIntent().getExtras();
        console.log("getExtras vale qualcosa -> " + extras);
    }   
} else if (args.ios) {
    // For iOS applications, args.ios is UIApplication.
    console.log("***** resumeEvent UIApplication: " + args.ios);
}

}); `

Any help is much appreciated!

deepak4u2006 commented 6 years ago

Hi @EddyVerbruggen, @priyangamani any help on this issue.

Aks659 commented 6 years ago

Duplicate of #269 . Please follow gist by nilsmehlhorn.

bpeterman commented 6 years ago

I found this: https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/platforms/android/libraryproject/firebase/src/main/java/org/nativescript/plugins/firebase/MyFirebaseMessagingService.java#L20

This concerns me that might have never worked if foreground is hardcoded to true. I'm also seeing this same issue on Android.

bpeterman commented 6 years ago

@EddyVerbruggen were you ever able to get background messages to come through? Digging through the code I don't see why it wouldn't work.

To be more specific the issue I'm seeing is when sending a data message (as described here https://firebase.google.com/docs/cloud-messaging/concept-options#data_messages) it doesn't seem to be invoking the onMessageReceived() method when the app is in the background.

Any details you can recall as you were implementing this would be helpful as I'm trying to implement a fix for this.

Sharique-Hasan commented 6 years ago

@bpeterman How are you fixing this? Could you please share it?

bpeterman commented 6 years ago

I'm trying to figure out what's going on first and why onMessageReceived() isn't getting called in the background.

Sharique-Hasan commented 6 years ago

@bpeterman Did you try this:

https://gist.github.com/nilsmehlhorn/1a3ee7447d0c7b60104288bc16c80c13

bpeterman commented 6 years ago

Does that work for you?

bpeterman commented 6 years ago

Maybe this is a different issue than what I am experiencing. I'll open a new issue.

ashokIosDev commented 5 years ago

Hi in ios, I'm facing the issue, i put this one LocalNotifications.addOnMessageReceivedCallback(notificationData => { in app.component.ts constructior but not calling, but notification was scheduled

hkurma commented 5 years ago

firebase.init({ showNotifications: true, showNotificationsWhenInForeground: true, onMessageReceivedCallback: (message: any) => { console.log("On firebase message recieved"); console.log(message); }, onPushTokenReceivedCallback: function (token) { console.log("Firebase push token: " + token); } }).then( () => { console.log("firebase.init done"); }, error => { console.log(firebase.init error: ${error}); } );

I get the log statements from callback when the app is in the foreground and receives a notification But when the app is in the background i receive the notification but the logs statements in onMessageReceivedCallback() are not executed.

Any think on this issue?

hkurma commented 5 years ago

Sorry, I figured it out. Thank you

timostuebing commented 4 years ago

but how!? :D Having the same problem!

mlars84 commented 2 years ago

@hkurma - How did you "figure it out"?