Notifications

To access to configured notifications go to menu Components > jBackend > Notifications. A list of notifications will be shown:

jBackend Notifications

Each notification has the following information:

Field: Description:
Title Notification title (used only on Android)
Message Notification message
Payload Payload of push notification for app (JSON format)
App App code
Platform OS platform
Target Target registered devices for the push notification (All, Selected users, Selected groups, Selected devices)
Target Users Users whose registered devices are target for the push notification
Target Groups Groups whose registered devices are target for the push notification
Target Devices Registerd devices target of the push notification
Context Application specific notification context. Not used yet (it will be used to filter recipients for push notifications)
Scheduled time Time scheduled to start sending out this notification on devices
Status Current sending status for this notification
Last run Last time this notification queue has been executed
Last device ID Device ID of the last notification sent in the last run

The Status of a notification can be:

Status: Description:
aborted (-2) The notification is "logically" deleted (in this state the notification is always skipped)
paused (-1) The notification is suspended (in this state the notification is always skipped)
scheduled (0) The notification is ready to be sent (sending will start at the scheduled time)
running (1) The notification is currently being processed
completed (2) The notification has been sent to all devices (job completed)

Using the buttons on the toolbar it is possible to change the status of selected notifications. It is also possible to "unlock" locked notifications. It could be useful, as example, when a notification is locked for too long, which could mean there was a problem on the scheduler and the resource was not released properly (see How notification sending works)

Since jBackend 3.3.0 each notification sent is logged into a database table. A management interface to access these logs will be provided in the next future.

How notification sending works

To start processing the pending notifications (with status scheduled and running) it is necessary to call a "trigger" function. The Push Module has a scheduler function that must be called on a regular basis (e.g. from a crontab) to trigger the sending of scheduled push notifications.

Scheduler logic

Each time the scheduler function is called, it select all pending notifications ordered by the scheduler time ascending (first the notification scheduled before). To be "pending" a notification must have a scheduled time less then current time, must be in status scheduled or running, and must be no locked (locked means the notification is currently in charge of another scheduler). If the pending list is not empty, the scheduler starts to process notifications once a time, until the total number of push notifications sent to devices reach the Batch size (max configured for the scheduler).

For the notification currently being processed, the scheduler first locks it, then start to send the notifications to all matching devices (sorted by device ID, so all devices will be checked only once, including new devices added while the notification is running) until the Batch size is reached or the devices are finished. In the first case the notification is unlocked and the scheduler ends. In the second case the notification state is set to completed, it is unlocked and the scheduler starts to process the next notification (if one) with the same rules.

With this processing logic it is possible to schedule and execute concurrent schedulers to increase volume of push notifications sent.

Push notification payload

It is possible to send a custom payload with each push notification. The payload must be a valid JSON, example:

{
  "alert": {
    "alertId": "1404999843555",
    "alertStatus": false
  }
}

Or:

{
  "id": "25"
}

How to get the JSON payload in the mobile app depends on the framework used. The following is an example using Ionic Framework with this Cordova Push notification plugin:

https://github.com/phonegap-build/PushPlugin

Android GCM

In the jBackend push plugin the payload hasthe following structure:

    $payload = array(
      'title'      => $notification['title'],
      'message'    => $notification['message'],
      'icon'       => 'icon',
      'data'       => $notification['payload']
    );

On the mobile app the push callback has the following code:

    window.onNotificationGCM = function(e) {
        switch (e.event) {
            case 'registered':
                if (e.regid.length > 0) {
                    $rootScope.$emit('push.registered', { 'token': e.regid });
                }
                break;
            case 'message':
                // Notification in foreground
                if (e.foreground) {
                    $log.debug('push notification in foreground');
                } else {
                    $log.debug('push notification in background');
                }
                $log.debug('push message payload ' + JSON.stringify(e.payload));
                $rootScope.$emit('push.received', { 'payload': e.payload.data });
                // e.payload.data is { "id": "25" }
                break;
            case 'error':
                $log.debug('push GCM error ' + e.msg);
                break;
            default:
                $log.debug('push GCM unknown event');
                break;
        }
    };

Apple APNs

In the jBackend push plugin the payload hasthe following structure:

    $body = array(
      'aps' => array(
          'alert' => array(
              'title' => $notification['title'],
              'body' => $notification['message']
          ),
          'sound' => 'default'
      ),
      'data' => $notification['payload']
    );

On the mobile app the push callback has the following code:

    window.onNotificationAPN = function(e) {
        if (e.alert) {
            $log.debug('push APN alert ' + e.alert);
        }
        if (e.sound) {
            $log.debug('push APN sound');
        }
        if (e.badge) {
            $log.debug('push APN badge ' + e.badge);
            pushNotification.setApplicationIconBadgeNumber(successBadgeHandler, errorBadgeHandler, e.badge);
        }
        $log.debug('push APN full event ' + JSON.stringify(e));
        $rootScope.$emit('push.received', JSON.parse(e.data));
        // e.data is { "id": "25" }
    };