Ionic / Cordova app does not receive push notification in background

My Android app does not receive push notifications in the background and should be consistent with the documentation .

The Android application on the Android device does not need to be launched to receive messages. The system will wake the Android application through Intent when a message arrives while the application is configured with the correct broadcast receiver and permissions.

An attempt at various notifications found that it receives push notifications while it is closed, if and only if the notifications contain the attribute "message , if not, it just discards it. (Push notifications are just JSON objects).

My notifications contain all kinds of attributes, including "alert", "id" and "title", but only the "message" makes Android wake the application.

Example notification that does not work :

{ event: 'message', from: '947957531940', collapse_key: 'do_not_collapse', foreground: true, payload: { alert: 'Mensaje de Prueba', title: 'Titulo Mensaje de Prueba' } } 

Example notification of what works :

 { event: 'message', from: '947957531940', message: 'Contenido del mensaje de prueba.', collapse_key: 'do_not_collapse', foreground: true, payload: { alert: 'Mensaje de Prueba', title: 'Titulo Mensaje de Prueba', message: 'Contenido del mensaje de prueba.' } } 

Is this the Android standard in design, or am I doing something wrong in my application?

My app was developed using Ionic with Cordova.

PD: Sorry my English.

EDIT:

This is the push code for Android inside the .run module in app.js, as ng-cordova indicates:

 if (ionic.Platform.isAndroid()){ var androidConfig = { "senderID": "94*************", "ecb": "window.casosPush" }; try{ var pushNotification = window.plugins.pushNotification; } catch (ex){ } // Llamada en caso de exito var successfn = function(result){ //alert("Success: " + result); }; // Llamada en caso de error var errorfn = function(result){ window.alert("Error: " + result); }; // Llamada de casos de notificacion push window.casosPush = function(notification){ switch (notification.event){ case 'registered': if (notification.regid.length > 0){ $rootScope.data.token = notification.regid; //alert('registration ID = ' + notification.regid); } break; case 'message': $rootScope.mensajes.unshift(notification.payload); $localstorage.setArray('mensajes', $rootScope.mensajes); alert(JSON.stringify(notification)); break; case 'error': alert('GCM error = ' + notification.msg); break; default: alert('An unknown GCM event has occurred'); break; } }; try{ // Llamada de registro con la plataforma GCM pushNotification.register(successfn,errorfn,androidConfig); } catch(notification){ } } 
+4
source share
2 answers

After searching all the questions in stackoverflow using Cordova / Phonegap Push Plugin, I found the source of the problem. It is written to the source code of the plugin, and it should not.

The problem was that the source code of the plugin requires the push notification to have a “message” field in order to trigger the notification while in the background. It is specified in the GCMIntentService.java file.

 if (extras.getString("message") != null && extras.getString("message").length() != 0) { createNotification(context, extras); } 

The most useful are the posts and issue in the plugin repository. Therefore, since I do not have authority over the action of the push server, I cannot specify the "message" field in push notifications, I had no alternative but to rewrite the source code.

So, I rewrote the te code as follows:

 @Override protected void onMessage(Context context, Intent intent) { Log.d(TAG, "onMessage - context: " + context); // Extract the payload from the message Bundle extras = intent.getExtras(); if (extras != null) { // if we are in the foreground, just surface the payload, else post it to the statusbar if (PushPlugin.isInForeground()) { extras.putBoolean("foreground", true); PushPlugin.sendExtras(extras); } else { extras.putBoolean("foreground", false); // Send a notification if there is a message //if (extras.getString("message") != null && extras.getString("message").length() != 0) { if (extras.getString("alert") != null && extras.getString("alert").length() != 0) { createNotification(context, extras); } } } } 

Thus, the plugin triggers a local notification if it receives push notifications with the field "alert" instead of "message".

Then I changed the code for local notification:

 public void createNotification(Context context, Bundle extras) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); String appName = getAppName(this); Intent notificationIntent = new Intent(this, PushHandlerActivity.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); notificationIntent.putExtra("pushBundle", extras); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); int defaults = Notification.DEFAULT_ALL; if (extras.getString("defaults") != null) { try { defaults = Integer.parseInt(extras.getString("defaults")); } catch (NumberFormatException e) {} } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setDefaults(defaults) .setSmallIcon(context.getApplicationInfo().icon) .setWhen(System.currentTimeMillis()) //.setContentTitle(extras.getString("title")) .setContentTitle(extras.getString("alert")) //.setTicker(extras.getString("title")) .setTicker(extras.getString("alert")) .setContentIntent(contentIntent) .setAutoCancel(true); /* String message = extras.getString("message"); if (message != null) { mBuilder.setContentText(message); } else { mBuilder.setContentText("<missing message content>"); } */ // Agregado mensaje predefinido mBuilder.setContentText("Haz clic para más información"); String msgcnt = extras.getString("msgcnt"); if (msgcnt != null) { mBuilder.setNumber(Integer.parseInt(msgcnt)); } int notId = 0; try { notId = Integer.parseInt(extras.getString("notId")); } catch(NumberFormatException e) { Log.e(TAG, "Number format exception - Error parsing Notification ID: " + e.getMessage()); } catch(Exception e) { Log.e(TAG, "Number format exception - Error parsing Notification ID" + e.getMessage()); } mNotificationManager.notify((String) appName, notId, mBuilder.build()); } 

Now the notification in the notification panel will first display the "alert" field instead of the "title" and the second predefined message instead of the "message" field, which does not exist in my push notifications.

Then I just recompile the code with:

 ionic platform rm android ionic platform add android ionic run android 

So, children, this is what happens when you write a plugin for everyone, but you do not consider common cases, and you do not document well. This plugin is only useful for people with a message and title field in their push notifications.

I lost two days of my internship because of this, I spent my time writing this so that others would not have to.

+7
source

You are right @David prieto. The problem was that the source code of the plugin requires the push notification to have a “message” field in order to trigger the notification while in the background.

There is one way to put the message field in a push notification and its simple. A payload array that has notification data that is sent through the API. It should have a message box. Thus, the push notification will automatically have a message field in it, and it will be detected both in the background and in the foreground.

+2
source

All Articles