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.

Channel-based broadcasting
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:
- 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.
- 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
Channel-based push notification example
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.
ARTMessage *message = [[ARTMessage alloc] initWithName:@"example" data:@"rest data"];
message.extras = @{
@"push": @{
@"notification": @{
@"title": @"Hello from Ably!",
@"body": @"Example push notification from Ably."
},
@"data": @{
@"foo": @"bar",
@"baz": @"qux"
}
}
};
[[rest.channels get:@"pushenabled:foo"] publish:@[message]];
CopyCopied!
Direct publishing
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, ordeviceToken
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.
Publish to a device ID example
var recipient = {
deviceId: 'xxxxxxxxxxx'
};
var data = {
notification: {
title: 'Hello from Ably!',
body: 'Example push notification from Ably.'
}
};
rest.push.admin.publish(recipient, data);
CopyCopied!
Publish to a client ID example
var recipient = {
clientId: 'bob'
};
var notification = {
notification: {
title: 'Hello from Ably!',
body: 'Example push notification from Ably.'
}
};
rest.push.admin.publish(recipient, notification);
CopyCopied!
Publish direct to a recipient example
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)
CopyCopied!
Push payload structure
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>,
...
}
}
CopyCopied!
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"
}
}
CopyCopied!
would be delivered in raw format to FCM as:
{
"collapse_key": "chat"
}
CopyCopied!
and would be delivered in raw format to APNs as:
{
"aps.thread-id": "chat"
}
CopyCopied!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:
CopyCopied!
- 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"
}
}
}
CopyCopied!
APNs Headers
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"
}
}
}
CopyCopied!