cordova-plugin-firebase: (Android) Click on notification doesn´t trigger onNotificationOpen callback

Cordova 6.3.1 Phonegap firebase plugin 0.1.12 Device: LG G5 with Android 6.0.1

This is the code I am using: `var app = { // Application Constructor initialize: function () { this.bindEvents(); }, // Bind Event Listeners // // Bind any events that are required on startup. Common events are: // ‘load’, ‘deviceready’, ‘offline’, and ‘online’. bindEvents: function () { document.addEventListener(‘deviceready’, this.onDeviceReady, false); }, // deviceready Event Handler // // The scope of ‘this’ is the event. In order to call the ‘receivedEvent’ // function, we must explicitly call ‘app.receivedEvent(…);’ onDeviceReady: function () { console.log (“Estamos en onDeviceReady”); if (navigator.connection.type == Connection.NONE) { navigator.notification.alert(‘Se requiere conexión a Internet’); } else { window.FirebasePlugin.onNotificationOpen(function(notification) { console.log(notification); navigator.notification.alert (“Recibido”); }, function(error) { console.log(error); }); } },

}; app.initialize();`

I receive notifications in the tray of system in all the situations: app in background, foreground and closed and when I click on notification, app is open in the three cases but callback is not triggered.

Is there anything wrong in the code?

Thanks in advance.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 6
  • Comments: 28 (7 by maintainers)

Most upvoted comments

I have re-written the whole onNotificationOpen handling and have it almost working as I would expect, which is:

  • Notification arrives with client in forground, open notification and onNotificationOpen is called in the current client (without reload)
  • Notification arrives with client in background, open notification and client is brought into forground and onNotificationOpen is called with current client (without reload)

The only thing remaining is to have the notification delivered immediately to the client without needing to be opened, if that’s at all possible (haven’t looked into it yet).

I am a bit of an Android noob, so there may be some improvements that can be made, but it seems to work ok, so thought I would share.

OnNotificationOpenReceiver:onReceive now simply calls

FirebasePlugin.onBroadcastReceive(context, intent);

Changed FirebasePlugin as follows

  • remove WeakReference from callbackContext
  • add onBroadcastReceive method, passes intent data to onNotificationOpen
  • add onNewIntent method, passes intent data to onNotificationOpen
  • restored old version of onNotificationOpen and changed it as follows
    • removed WeakReference line
    • Change callbacks to use a PluginResult and call setKeepCallback(true) on the result to prevent the callback from being removed after the first call
    private static CallbackContext callbackContext;
    // ...
    private void registerOnNotificationOpen(final CallbackContext callbackContext) {
        FirebasePlugin.callbackContext = callbackContext;
    }

    // called when in foreground
    public static void onBroadcastReceive(Context context, Intent intent) {
        Log.d("FirebasePlugin", "onBroadcastReceive");
        Bundle data = intent.getExtras();
        FirebasePlugin.onNotificationOpen(data);
    }

    // called when in background
    @Override
    public void onNewIntent(Intent intent) {
        Log.d(TAG, "new intent " + intent);
        super.onNewIntent(intent);
        FirebasePlugin.onNotificationOpen(intent.getExtras());
    }

    public static void onNotificationOpen(Bundle bundle) {
        if (FirebasePlugin.callbackContext == null ) {
            Log.d("FirebasePlugin", "no callback context, onNotificationOpen ignored");
            return;
        }
        if (callbackContext != null && bundle != null) {
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    json.put(key, bundle.get(key));
                } catch (JSONException e) {
                    Log.d("FirebasePlugin", "onNotificationOpen: json exception");
                    PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                    return;
                }
            }
            Log.d("FirebasePlugin", "onNotificationOpen: send notification to javascript");
            PluginResult result = new PluginResult(PluginResult.Status.OK, json);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);
        }
    }

Ok here it is https://gist.github.com/Mehuge/374ee24d9e18a6c7ccc171d3e521b7ad

Note however, that there are a few bits in there that are specific to our app. I ended up moving the code into our project because I was changing it about so much. In hindsight, I should probably have forked the plugin and modified it that way, but by this point, I was way behind schedule and quite fed up with the whole thing, so I took the quickest route to getting something working. The custom bits are fairly obvious, so should be easy enough to exclude.

Note also that the way I have implemented the plugin, it needs to know when the client is paused (or more specifically not paused) so it can decide if to create a notification or deliver the message directly. You may or may not need that functionality, but in our case, we didn’t want notifications that were sent when the client was in the foreground to create android notifications but instead be delivered directly to the client to handle. To inform the plugin of the pause state of the client, add the following code to your main activity.

@Override
protected void onResume() {
    FirebasePlugin.setPaused(false);
    super.onResume();
}

@Override
protected void onPause() {
    FirebasePlugin.setPaused(true);
    super.onPause();
}

There is another issue that you may have to contend with, which is if a notification arrives while in the background but the user launches the app directly rather than by opening the android notification you may need to deal with that in some way. In our apps case, I could just clear any unopened notifications. Your situation may be different.

I am not entirely happy with the final result, some of the extra keys added for example were experimental and are not actually being used, I just have not got around to removing them.

Would be interested in any feedback or suggested improvements or pointing out any flaws. I would be particularly interested in finding a way to better detect a launch intent with a GCM payload from a normal launch. I found the google properties are only added in some circumstances. Also my attempts at detecting the different types of notifications (is_push, is_notify, broadcast) are not really working.

@BugsBunnyBR I just tested to switch to the github repo and found that tapping on a notification restarts my app even if it is already running. Happens even when the app is in foreground and i tap on the notification. But the callback works now 😉

Same here, for me the version 0.1.13 is causing my app restart just when it is in foreground. Version 0.1.12 is working just fine.

https://firebase.google.com/docs/cloud-messaging/android/receive Here it is described very well. Your Notification goes to the System-Tray if the app is in the background and to the onMessageReceived() if the app is in foreground. If your message contains data then this is always passed to the onMessageReceived().

I think that there is a problem in the implementation of onMessageReceived(). When I look to the code I interpret is as follow:

  • extract data
  • building a notification with NotificationBuilder
  • notify via NotificationManager

NotificationManager.notify(id, notification) posts the notification to be shown in the Status Bar.

However, for me this seems to be expected that everytime I receive a message from FCM then it will be shown a notification in the Status Bar. I don’t see any check if the App is in foreground and I don’t see any call to the callback. I am no Android developer so maybe I am wrong but the described behaviour fits to that.

@Mehuge would you mind creating gists with all files you have?

Why dont we create a pull request with that code @Mehuge posted ?It works like charm on android for me.

OK, I found the piece of code that calls the callback. With the last commit from BugsBunnyBR there was change in the OnNotificationOpenReceiver which explains that arivanbastos gets his callback executed when pointing to the github repo.

But still, the notification gets only send (to the OnNotificationOpenReceiver and the NotificationManager) if there is either a text or title (in notification or in data). That means it is not possible to send data to your app without getting the notification send to the NotificationManager which shows it in the StatusBar.

Installing from github partially solved the problem. Thank you.

cordova plugin remove cordova-plugin-firebase
cordova plugin add https://github.com/arnesson/cordova-plugin-firebase/

Now the onNotificationOpen() callback is called when the app is in background. When the app is in foreground, rather than documentation says, the notification arrives and the onNotificationOpen() is not called:

App is in foreground: User receives the notification data in the JavaScript callback without any notification on the device itself (this is the normal behaviour of push notifications, it is up to you, the developer, to notify the user)

@superheroben , could you provide a repo with a sample of how you are calling the plugin code? How are you sending the notifications? I tested with topic messages.