Publish and receive push notifications
Publishing sends push notifications to all specified devices or browsers either directly or via channels. This process is facilitated by Ably’s realtime messaging infrastructure, which ensures that messages and notifications are delivered instantaneously.
Publish push notifications directly or via channels:
- Publish directly
- Description: Messages are sent directly to specified devices or browsers without the need for channel subscriptions.
- Requirement: Relies on
deviceIds
,clientIds
and recipient attributes to target messages directly to devices or browsers.
- Publish via channels
- Description: Messages are sent to multiple devices or browsers through specified channels.
- Requirement: Devices or browsers must be subscribed to these channels to receive notifications.
Push notification payload structure
Ably adapts message fields for seamless compatibility with each push notification platform:
- Ably field
- The message field in Ably.
- FCM Field
- Field mapping in Firebase Cloud Messaging.
- APNs
- Field mapping in Apple Push Notification service.
- Web Push
- Field mapping in the Notification API.
The following table shows how the mapping works:
Ably field | FCM | APNs | Web Push |
notification.title | notification.title | aps.alert.title | notification.title |
notification.body | notification.body | aps.alert.body | notification.body |
notification.icon | notification.icon | Discarded | notification.icon |
notification.sound | notification.sound | aps.alert.sound | Discarded |
notification.collapseKey | collapse_key | aps.thread-id | Discarded |
data | data | Merged into root object | notification.data |
The following examples show how Ably transforms each field:
{
// General notification structure
"notification": {
"collapseKey": "chat"
}
}
// Equivalent raw format for FCM
{
"collapse_key": "chat"
}
// Equivalent raw format for APNs
{
"aps.thread-id": "chat"
}
CopyCopied!
You can also override generic values for a field or add specific fields not supported in the general structure. The following is an example of overriding the title for iOS and setting a specific background color for Android:
// Example payload structure with specific customizations for APNs and FCM
{
"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"
}
},
"web": {
"badge": "/badge.png"
}
}
CopyCopied!
APNs Headers
To enable background notifications on iOS, you must include specific headers in the notification. You can specify these headers by adding an apns-headers
object, which should contain all the desired APNs headers, as part of the apns
object.
The following example shows a background notification:
{
"data": {
"foo": "bar",
"baz": "qux"
},
"apns": {
"aps": {
"content-available": 1,
},
"apns-headers": {
"apns-push-type": "background",
"apns-priority": "5"
}
}
}
CopyCopied!
Publish directly
Direct publishing sends push notifications directly to individual devices via the Ably SDK, bypassing the intermediary of channels. This approach delivers personalized or precise notifications customized for individual users. Direct publishing proves beneficial during the transition phase to Ably’s platform and when the objective is to engage existing push notification devices.
Push notifications are targeted explicitly towards devices identified by:
Publish directly using deviceId
For applications requiring direct targeting of individual devices or browsers, using the deviceId
allows for precise control over where each push notification is sent. This approach is ideal when notifications are intended for a specific device or browser, such as alerting users about actions required on a particular device or browser or sending device-specific or server-specific updates.
A deviceId
is set during the device or browser activation process.
The following example publishes a push notification using the deviceId
:
var recipient = {
deviceId: 'xxxxxxxxxxx'
};
var data = {
notification: {
title: 'Hello from Ably!',
body: 'Example push notification from Ably.'
}
};
realtime.push.admin.publish(recipient, data);
CopyCopied!
Publish directly using clientId
When you need to deliver push notifications to a specific user rather than a single device, you can use the clientId
to target all devices associated with a particular user. This process is particularly useful for applications where users may have multiple devices or browsers, and you want to ensure that all devices or browsers receive the notifications seamlessly.
A clientId
is set during the device or browser activation process.
The following example publishes a push notification using the clientId
:
var recipient = {
clientId: 'bob'
};
var notification = {
notification: {
title: 'Hello from Ably!',
body: 'Example push notification from Ably.'
}
};
realtime.push.admin.publish(recipient, notification);
CopyCopied!
Publish directly using recipient attributes
Direct publishing using recipient attributes allows for a highly tailored approach to sending notifications based on specific criteria such as device tokens or transport types. This method is particularly effective when engaging users across different platforms or devices with customized messages.
Recipient attributes are set during the device or browser activation process.
The following example publishes a push notification using the recipient attributes:
var recipient = {
transportType: 'apns',
deviceToken: 'xxxxxxxxxx'
};
var notification = {
notification: {
title: 'Hello from Ably!',
body: 'Example push notification from Ably.'
}
};
realtime.push.admin.publish(recipient, notification);
CopyCopied!
Publish via channels
Publishing via channels is modeled on Ably’s channel infrastructure, facilitating the delivery of push notifications across a network of subscribed devices or browsers. This process publishes messages through predefined channels, which devices or browsers must subscribe to in order to receive updates. This process ensures registered devices or browsers in the specified channels receive the correct push notifications. Publishing via channels is particularly useful for publishing notifications to multiple groups with varying privileges.
It’s important to distinguish — subscribing to push notifications differs from subscribing to ordinary messages, as it requires a specific action to receive updates.
Subscribe to channels
Subscribe to Ably channels only if you are publishing push notifications via channels process. You can subscribe using either deviceId
or clientId
. For the client to register with Ably automatically, it must be authenticated and possess the necessary push-subscribe
capability.
The following example shows how to subscribe for push notifications using deviceId
by calling the push.subscribeDevice()
method:
const channel = realtime.channels.get("pushenabled:foo");
await channel.subscribeDevice();
CopyCopied!
The following example shows how to subscribe for push notifications using clientId
by calling the push.subscribeClient()
method:
const channel = realtime.channels.get("pushenabled:foo");
await channel.subscribeClient();
CopyCopied!
Publish via channels process
Publishing via channels mirrors the process of sending standard messages to subscribers in realtime via Ably’s pub/sub channels. When a message is sent on an Ably channel, it’s immediately published to all channel subscribers.
Note that the device will receive a push notification published on a channel only if:
- The published message includes the extra push notification payload.
- You explicitly configure a channel rule to enable push notifications on that channel.
- The device or browser subscribes to the channel.
- The push notification payload is compatible with the device or browser.
Add push notifications as special payloads in a standard Ably message’s extras
field. Ensure this field includes a push
attribute object specifying 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 = realtime.channels.get('pushenabled:foo');
await channel.publish({ name: 'example', data: 'data', extras: extras });
CopyCopied!