Push Notifications - Publishing Notifications

Ably provides two models for delivering push notifications to devices. Channel-based broadcasting provides automatic fan-out capabilities for push notifications, and direct publishing provides a means to deliver individual notifications to devices.

Push Notifications in Ably

The model for delivering push notifications to devices over channels is intentionally very similar to how normal messages are delivered to realtime subscribers using Ably’s pub/sub channels. For example, a normal message published on an Ably channel is broadcast immediately to all subscribers of that channel. When broadcasting push notifications on channels, however, the process is the same with the exception that the subscribers (devices receiving push notifications) are registered in advance using our API and the message itself must contain an extra push notification payload that specifies the optional visual format and optional data payload of the push notification.

Therefore, the process for delivering push notifications to devices using channel-based broadcasting is as follows:

  1. Create one or more push subscriptions to the channel. These can be by device ID to subscribe individual devices or by client ID to subscribe all devices with that client ID.
  2. Publish a message on the channel with a push notification payload

Please note that a push notification published on a channel will only be delivered to a device if:

  • the extra push notification payload is included in the published message
  • a channel rule is configured explicitly enabling push notifications on that channel
  • the device is subscribed to the channel
  • the push notification payload is compatible with the subscribed push notification device

Push notifications are sent as special payloads alongside a normal Ably message in the extras field. The extras field is an object and must contain a push attribute object with the push payload details.

var extras = { push: { notification: { title: 'Hello from Ably!', body: 'Example push notification from Ably.' }, data: { foo: 'bar', baz: 'qux' } } }; const channel = rest.channels.get('pushenabled:foo'); await channel.publish({ name: 'example', data: 'data', extras: extras });

Ably provides an API that allows push notifications to be delivered directly to:

  • Devices identified by their unique device ID
  • Devices identified by their assigned clientId
  • Devices identified by their recipient attributes such as their unique registrationToken in the case of FCM, or deviceToken in the case of APNs.

    This is particularly useful when migrating to Ably with existing push notification target devices.

See the push admin publish documentation for the client library API details, and the raw push publish REST API documentation for information on the underlying direct publishing endpoint used by the client libraries.

var recipient = { deviceId: 'xxxxxxxxxxx' }; var data = { notification: { title: 'Hello from Ably!', body: 'Example push notification from Ably.' } }; await rest.push.admin.publish(recipient, data);

var recipient = { clientId: 'bob' }; var notification = { notification: { title: 'Hello from Ably!', body: 'Example push notification from Ably.' } }; rest.push.admin.publish(recipient, notification);

recipient = { transport_type: 'apns', device_token: 'xxxxxxxxxx' } notification = { notification: { title: 'Hello from Ably!', body: 'Example push notification from Ably.' } } rest.push.admin.publish(recipient, notification)

A push notification payload has a generic structure as follows:

{ "notification": { "title": <string, title to display at the notification>, "body": <string, text below title on the expanded notification>, "icon": <string, platform-specific>, "sound": <string, platform-specific>, "collapseKey": <string, platform-specific, used to group notifications together> }, "data": { <key string>: <value string>, ... } }

Depending on the transport (APNs, FCM, etc.), the following transformations are made automatically by Ably to make each field compatible with the target push notification transport:

Ably field FCM APNs
notification.title notification.title aps.alert.title
notification.body notification.body aps.alert.body
notification.icon notification.icon Discarded.
notification.sound notification.sound aps.alert.sound
notification.collapseKey collapse_key aps.thread-id
data data Merged into root object.

So for example, a push payload in a message published to Ably as follows:

{ "notification": { "collapseKey": "chat" } }

would be delivered in raw format to FCM as:

{ "collapse_key": "chat" }

and would be delivered in raw format to APNs as:

{ "aps.thread-id": "chat" }
Additionally, you can set transport-specific attributes which will get merged into the root object resulting from generic mapping explained above only when pushing to the selected transport. This way, you can:

  • Override the generic value for that field.
  • Add specific fields that are not supported in the generic structure.

To do this, alongside notification and data, add an object whose field is one of:

Here’s an example of a push payload that overrides the default title for APNs iOS and sets the FCM Android-specific color field:

{ "notification": { "title": "Hello from Ably!", "body": "Example push notification from Ably." }, "data": { "foo": "bar", "baz": "qux" }, "apns": { "aps": { "alert": { "title": "Hello to iOS from Ably!" } } }, "fcm": { "notification": { "color": "#d3d3d3" } } }

Some features such as background notifications on iOS require particular headers to be included in the notification. Headers can be specified by adding an apns-headers object containing all desired APNs headers as part of the apns object. For example a background notification may look like:

{ "data": { "foo": "bar", "baz": "qux" }, "apns": { "aps": { "content-available": 1, }, "apns-headers": { "apns-push-type": "background", "apns-priority": "5" } } }
Channel-based broadcasting