Phonegap Firebase Push Notification not firing event listener when app opens, or when app is in background
Asked Answered
S

2

9

I'm using Phonegap and Firebase (fcm) to receive push notifications. I am using Android 8 to test.

I want my device to receive a push notification if the app is running in the foreground (as a popup message in the app). If the app is closed or in the background I want the message to be shown as a notification, and when I click on the notification it opens the app in the foreground and calls the notification event function.

Here is what happens so far:

  • When the app is open a push notification comes through and is displayed in the app - CORRECT

  • When the app is minimised a push notification appears in the top bar - CORRECT...but

  • When I click the notification message it opens my app / puts it in foreground, but the "notification" event listener is not called - INCORRECT

There are a lot of requests for help regarding this issue and I have gone through many of them but none of them offer a working solution for my app (most are between 2016 and 2018, not 2019).

Primarily this needs to work for Android. Therefore I have tried removing the notification payload and only using the data payload. However this doesn't solve the problem.

Here is my current payload:

$notification = array
(
'body'   => 'test',
'title'     => 'test',
"icon" =>  'notification_icon',
"content_available" => true,
);

$data = array
(
"title" => "test",
"body" => "test",
"icon" => "notification_icon",
"content_available" => true,
);

$fields = array
(
'registration_ids'  => $registrationIds,
'notification'      => $notification,
'data'          => $data,
"priority" => "high",
"content_available" => true 
);

As I understand it there are 3 ways to send a notification:

1) as "notification". This works in the foreground if the app is currently running, or in the background in the top bar if the app is closed or minimised (and the icon for the app has a little badge above it indicating a message) but when in the background, when the message is clicked on the app loads but the on notification function IS NOT called.

2) as "data". This ONLY seems to work in the foreground, with no top bar message and the icon for the app does not have a little badge above it. If the app is in the background there is no push notification at all.

3) as BOTH "notificaton" and "data". When in the background the app icon has a badge above it. When the top bar message is clicked the app is loaded but the on notification function IS NOT called.

Also, even with the app in the background, if it receives a push notification and put the app in to the froeground no notification message is shown. It only works if the app is already in the foreground when the notification is received.

Here are my event listeners:

var app = {
initialize: function() {
    this.bindEvents();
},
bindEvents: function() {
    document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
  console.log('Received Device Ready Event');
  app.setupPush();
},
setupPush: function() {
    var push = PushNotification.init({
      android: {
        senderID: 'XXXXXXXXXX',  
        iconColor: "#ccc",
        alert: true,
        badge: true,
        icon: 'notification_icon',
        sound: true,
        vibrate: true,
      },
      browser: {},
      ios: {
        sound: true,
        vibration: true,
        badge: true
      },
      windows: {}
    });
    console.log('after init');

    push.on('registration', function(data) {
         //[edit - script not displayed for this example, but it registers a token to enable push notifications to the device. tested and working]
    });

    push.on('error', function(e) {
      console.log('push error = ' + e.message);
    });

    push.on('notification', function(data) {
       window.alert(data.additionalData);              //Test line

      if(data.additionalData.foreground){
        window.alert(data.title+'\n'+data.message);    //Test line
      }
      if(data.additionalData.coldstart){
        window.alert("coldstart");                     //Test line
      }
      showPopup(data,"info");

    });


  }
};

//Using Sweet Alert to display messages

function showPopup(data,type){
   Swal.fire({
     type: type,
     title: data.title,
     text: data.message,
     showConfirmButton: true,
     imageUrl: data.image,
     imageWidth: 400,
     imageHeight: 200,
    imageAlt: data.title,
    animation: true,
  });
}

Does anybody have an answer to the above that works for Android 7 and 8?

Segregation answered 19/3, 2019 at 15:51 Comment(4)
Some people are reporting that it will work both in foreground, background and as a clickthrough from the notification if you exlude the "notification" object from the payload. However this does not seem to make a difference for Android 8, and excluding the notification payload will prevent it from working in IOS too.Segregation
More info here: github.com/phonegap/phonegap-plugin-push/issues/2575Segregation
Could you show us how you create and set the event listener for receiving notifications?Induna
Hi, yep, will update the question now.Segregation
S
0

My final answer, to get push messages working as both notification msg and in-app messages for Android devices (inc Android 8 and 9) was to do the following:

Add this to/modify from config.xml:

<preference name="phonegap-version" value="cli-9.0.0" />  
<platform name="android">
    <resource-file src="google-services.json" target="app/google-services.json" />
</platform>
<platform name="ios">
    <resource-file src="GoogleService-Info.plist" />    
</platform>
<plugin name="phonegap-plugin-push" spec="2.1.3">
    <variable name="SENDER_ID" value="xxxxxxxxxxxxx" />
</plugin>    

Also when sending your packet data, send the "data" parameter AND the "notification" parameter, AND include the "content_available" flag, eg...

  $notification = [
                'body'   => $message,
                'title'     => $titlenotification,                    
                "icon" =>  'notification_icon',
                "content_available" => "1", 
  ];


 $data = [
             "title"             =>$titlenotification,  
             "message"           => $message,
             "content_available" => "1",
 ];

 $fields =  [
            'registration_ids'   => $registrationtokens,    
             'notification'      => $notification,        
            'data'               => $data,                         
            "priority"           => "high",
            "content_available"  => true,
 ];

 //send field data like curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

...finally, be sure to add your google-services.json to the root folder, but also the www folder. Otherwise you will receive the error "A plugin requires google-services.json. The Google Services Plugin cannot function without it" when Phonegap Build is processing it.

This will show an notification message if the app is closed or in the background. when you click the notification it will open the app AND show the message again. If your app is in the background, when you bring it to the foreground is WILL show the message too. If your app is closed and you dont click the notification message then you will never see the message on your app.

Segregation answered 19/11, 2019 at 10:38 Comment(0)
C
4

Your notification send logic is solid, but your concerns are also valid. If you want to read more on the subject, google notification vs data notifications, there are some good articles explaining it.

Push notifications have a special native on open receiver, your WebView must register for those events. However, if you look at the source, notification open events are not handled. There's nothing you can do short of forking the repository.

Furthermore, .on('notification') events are not received by your WebView when the app is killed because.. well, your app is killed. Your app does not receive the notification when it is killed, Android OS receives it and decides what to do with it.

As to why you noticed the issue on Android 8, recent versions of Androids have more aggressively been killing apps in the background, to save battery: Doze and Adaptive battery. Newer android apps are simply being killed off sooner.

If at all possible, I advise you to switch to cordova-plugin-firebase, a more actively-maintained plugin. Alternatively, learn a bit of android and write your own plugin.

Chichi answered 20/5, 2019 at 16:30 Comment(4)
Thanks for the reply. Even if the app is in the background it never receives the on("notification") event. Perhaps, as you say, due to more aggresive battery saving techniques all events on apps running in the background are ignored, and only the main foreground app will receive anything. This is a real shame for the app I am making. I tried using cordova-plugin-firebase but I found it quite buggy.Segregation
As I mentioned, for your case, it does not matter if on("notification") is called or not. You need to listen to onNotificationOpen events, and you can do that with cordova-plugin-firebase even when your app is killed. window.FirebasePlugin.onNotificationOpen is the event. As for the bugs, FirebasePlugin encountered some issues with the latest Google APIs release (7 May). You can fix that by fixating dependency numbers in your project.properties file (this is not a solution, it is a workaround):Chichi
cordova.system.library.4=com.google.firebase:firebase-core:16.0.8 cordova.system.library.5=com.google.firebase:firebase-messaging:17.5.0 cordova.system.library.6=com.google.firebase:firebase-config:16.4.1 cordova.system.library.7=com.google.firebase:firebase-perf:16.2.4Chichi
Great, thanks I'll give it a try and get back to youSegregation
S
0

My final answer, to get push messages working as both notification msg and in-app messages for Android devices (inc Android 8 and 9) was to do the following:

Add this to/modify from config.xml:

<preference name="phonegap-version" value="cli-9.0.0" />  
<platform name="android">
    <resource-file src="google-services.json" target="app/google-services.json" />
</platform>
<platform name="ios">
    <resource-file src="GoogleService-Info.plist" />    
</platform>
<plugin name="phonegap-plugin-push" spec="2.1.3">
    <variable name="SENDER_ID" value="xxxxxxxxxxxxx" />
</plugin>    

Also when sending your packet data, send the "data" parameter AND the "notification" parameter, AND include the "content_available" flag, eg...

  $notification = [
                'body'   => $message,
                'title'     => $titlenotification,                    
                "icon" =>  'notification_icon',
                "content_available" => "1", 
  ];


 $data = [
             "title"             =>$titlenotification,  
             "message"           => $message,
             "content_available" => "1",
 ];

 $fields =  [
            'registration_ids'   => $registrationtokens,    
             'notification'      => $notification,        
            'data'               => $data,                         
            "priority"           => "high",
            "content_available"  => true,
 ];

 //send field data like curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

...finally, be sure to add your google-services.json to the root folder, but also the www folder. Otherwise you will receive the error "A plugin requires google-services.json. The Google Services Plugin cannot function without it" when Phonegap Build is processing it.

This will show an notification message if the app is closed or in the background. when you click the notification it will open the app AND show the message again. If your app is in the background, when you bring it to the foreground is WILL show the message too. If your app is closed and you dont click the notification message then you will never see the message on your app.

Segregation answered 19/11, 2019 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.