Push notification API (coming soon)
Centrifugo excels in delivering real-time in-app messages to online users. Sometimes though you need a way to engage offline users to come back to your app. Or trigger some update in the app while it's running in the background. That's where push notifications may be used. Push notifications delivered over battery-efficient platform-dependent transport.
With Centriufugo PRO push notifications may be delivered to all popular application platforms:
- Android devices
- iOS devices
- Web browsers which support Web Push API (Chrome, Firefox, see this matrix)
Centrifugo PRO provides API to manage user device tokens, device channel subscriptions and API to send push notifications towards registered devices and group of devices (subscribed to a channel).
To deliver push notifications to devices Centrifugo PRO integrates with the following providers:
- Firebase Cloud Messaging (FCM)
- Huawei Messaging Service (HMS) Push Kit
- Apple Push Notification service (APNs)
This means that Centrifugo PRO covers full flow of sending push notifications including frontend SDKs (provided by FCM, HMS, Apple SDKs).
All these push notification providers only manage frontend and transport part of notification delivery. Device token management and effective push notification broadcasting are parts to be solved by the application backend. Centrifugo PRO provides an API to store tokens in database (PostgreSQL), manage device subscriptions to channels in a unified way.
Centrifugo PRO comes with worker queues (based on Redis streams) which allow broadcasting push notifications towards devices in a very efficient way.
Integration with FCM means that you can use existing Firebase messaging SDKs to extract push notification token for a device on different platforms (iOS, Android, Flutter, web browser) and setting up push notification listeners. Only a couple of additional steps required to integrate frontend with Centrifugo PRO device token and device subscription storage. After doing that you will be able to send push notification towards single device, or towards devices subscribed to a channel. For example, with a simple Centrifugo API call like this:
curl -X POST http://localhost:8000/api \
-H "Authorization: apikey <KEY>" \
-d @- <<'EOF'
{
"method": "send_push_notification",
"params": {
"recipient": {"channels": ["test"]},
"notification": {
"fcm": {
"message": {
"notification": {"title": "Hello", "body": "How are you?"}
}
}
}
}
}
EOF
Motivation and design choices
Usually the first thing you'd do in the app to start delivering push notifications is integrating with huge providers like FCM, HMS, APNs. Integrating with these providers usually mean you need to keep device tokens in the application database and implement sending push messages to provider Push Services.
Centrifugo PRO provides the required backend for device tokens, and tries to follow best practices when working with tokens. It follows provider advices to keep only a working set of device tokens by reacting on errors and periodically removing stale devices/tokens.
Centrifugo PRO provides an efficient and scalable queuing mechanism for sending push notifications. Developers can send notifications from the app backend to Centrifugo API with a minimal latency, and let Centrifugo process sending to FCM, HMS, APNs concurrently from the built-in workers.
FCM and HMS have a built-in way of sending notification to large groups of devices over topics mechanism (the same for HMS). One problem with native FCM or HMS topics though is that client can subscribe to any topic from the frontend side without any permission check. In today's world this is usually not desired. So Centrifugo PRO re-implements FCM, HMS topics by introducing an additional API to manage device subscriptions to channels. We intentionally called it channels
to make the concept closer to our real-time API. In some cases you may have real-time channels and device subscription channels with matching names – to send messages to both online and offline users. Though it's up to you. Centrifugo PRO device subscriptions also add a way to introduce topic semantics for APNs.
Centrifugo PRO tries to avoid combining push notifications APIs for all supported providers into one unified API – just gives a way to send notification payloads in a format defined by each provider. This allows Centrifugo PRO to be a non-obtrusive proxy for all the mentioned providers.
Apart from this you get a possibility to inspect sent push notifications over our ClickHouse analytics. Also, providers may provide their own analytics. For example, FCM provides analytics from which you can get insight into push notification delivery.
One more thing – in our push API we left a possibility to send notifications into FCM, HMS topics or sending to raw FCM, HMS, APNs tokens, so you can combine native provider primitives with those added by Centrifugo (i.e. sending to a list of device IDs or to a list of channels).
Steps to integrate
- Add provider SDK on the frontend side, follow provider instructions for your platform to obtain a push token for a device. For example, for FCM see instructions for iOS, Android, Flutter, Web Browser). The same for HMS or APNs – frontend part should be handled by their native SDKs.
- Call Centrifugo PRO backend API with the obtained token. From the application backend call Centrifugo
device_register
API to register the device in Centrifugo PRO storage. - Centrifugo returns a registered device object, pass a generated device ID to the frontend and save it on the frontend together with a token received from FCM.
- Subscribe device to the required set of channels, first by calling your backend with device ID and list of channels, check channel permissions and then call Centrifugo
device_subscription_set
ordevice_subscription_add
APIs. - Call Centrifugo
send_push_notification
API whenever it's time to deliver a push notification.
At any moment you can inspect device and subscription storage by calling device_list
or device_subscription_list
APIs.
Also, you can remove unnecessary by using device_remove
or device_subscription_remove
APIs.
Configuration
In Centrifugo PRO you can configure one push provider or use all of them – this choice is up to you.
FCM
As mentioned above Centrifigo uses PostgreSQL for token storage. To enable push notifications make sure database
section defined in the configration and fcm
is in the push_notifications.enabled_providers
list. Centrifugo PRO uses Redis for queuing push notification requests, so Redis address should be configured also. Finally, to integrate with FCM a path to the credentials file must be provided (see how to create one in this instruction). So the full configuration to start sending push notifications over FCM may look like this:
{
...
"database": {
"dsn": "postgresql://postgres:[email protected]:5432/postgres"
},
"push_notifications": {
"redis_address": "localhost:6379",
"enabled_providers": ["fcm"],
"fcm_credentials_file_path": "/path/to/service/account/credentials.json"
}
}
Actually, PostgreSQL database configuration is optional here – you can use push notifications API without it. In this case you will be able to send notifications to FCM, HMS, APNs raw tokens, FCM and HMS native topics and conditions. I.e. using Centrifugo as an efficient proxy for push notifications (for example if you already keep tokens in your database). But sending to device ids and channels, and token/subscription management APIs won't be available for usage.
HMS
{
...
"database": {
"dsn": "postgresql://postgres:[email protected]:5432/postgres"
},
"push_notifications": {
"redis_address": "localhost:6379",
"enabled_providers": ["hms"],
"hms_app_id": "<your_app_id>",
"hms_app_secret": "<your_app_secret>",
}
}
See example how to get app id and app secret here.
APNs
{
...
"database": {
"dsn": "postgresql://postgres:[email protected]:5432/postgres"
},
"push_notifications": {
"redis_address": "localhost:6379",
"enabled_providers": ["apns"],
"apns_endpoint": "development",
"apns_bundle_id": "com.example.your_app",
"apns_auth": "token",
"apns_token_auth_key_path": "/path/to/auth/key/file.p8",
"apns_token_key_id": "<your_key_id>",
"apns_token_team_id": "your_team_id",
}
}
We also support auth over p12 certificates with the following options:
push_notifications.apns_cert_p12_path
push_notifications.apns_cert_p12_b64
push_notifications.apns_cert_p12_password
Other options
push_notifications.max_inactive_device_days
This option configures the number of days to keep device without updates. By default Centrifugo does not remove inactive devices.
API description
device_register
Registers or updates device information.
device_register request
Field | Type | Required | Description |
---|---|---|---|
id | string | No | ID of the device being registered (only provide when updating). |
provider | string | Yes | Provider of the device token (valid choices: fcm , hms , apns ). |
token | string | Yes | Push notification token for the device. |
platform | string | Yes | Platform of the device (valid choices: ios , android , web ). |
user | string | No | User associated with the device. |
meta | map<string, string> | No | Additional metadata for the device (not indexed). |
tags | map<string, string> | No | Additional tags for the device (indexed data). |
channels | array of strings | No | Device channel subscriptions. |
device_register result
Field Name | Type | Description |
---|---|---|
device | Device | The device that was registered. |
Device
:
Field Name | Type | Description |
---|---|---|
id | string | The device's ID. |
provider | string | The device's token provider. |
token | string | The device's token. |
platform | string | The device's platform. |
user | string | The user associated with the device. |
device_update
Call this method to update device. For example, when user logs out the app and you need to detach user ID from the device.
device_update request
TBD
device_update result
TBD
device_remove
Removes device from storage. This may be also called when user logs out the app and you don't need its device token after that.
device_remove request
Field Name | Type | Required | Description |
---|---|---|---|
ids | repeated string | No | A list of device IDs to be removed |
users | repeated string | No | A list of device user IDs to filter devices to remove |
provider_tokens | ProviderTokens | No | Provider tokens to remove |
device_remove result
Empty object.
device_list
Returns a paginated list of registered devices according to request filter conditions.
device_list request
Field | Type | Required | Description |
---|---|---|---|
ids | repeated string | No | List of device IDs to filter results. |
providers | repeated string | No | List of device token providers to filter results. |
tokens | repeated string | No | List of device tokens to filter results. |
platforms | repeated string | No | List of device platforms to filter results. |
users | repeated string | No | List of device users to filter results. |
since | string | No | Cursor for pagination (last device id in previous batch). |
limit | int32 | No | Maximum number of devices to retrieve. |
include_meta | bool | No | Flag indicating whether to include meta information for each device. |
device_list result
Field Name | Type | Description |
---|---|---|
items | repeated Device | A list of devices |
has_more | bool | A flag indicating whether there are more devices available |
push_user_channel_update
Manage mapping of channels with users. These user channels will be automatically attached to user devices upon registering.
push_user_channel_update request
TBD
push_user_channel_update result
TBD
push_user_channel_list
List user to channel mapping.
push_user_channel_list request
TBD
push_user_channel_list result
TBD
send_push_notification
Send push notification to specific device_ids
, or to channels
, or native provider identifiers like fcm_tokens
, or to fcm_topic
. Request will be queued by Centrifugo, consumed by Centrifugo built-in workers and sent to the provider API.
send_push_notification request
Field name | Type | Required | Description |
---|---|---|---|
recipient | PushRecipient | Yes | Recipient of push notification |
notification | PushNotification | Yes | Push notification to send |
PushRecipient
(you must set only one of the following fields):
Field | Type | Required | Description |
---|---|---|---|
device_ids | repeated string | No | Send to a list of device IDs |
channels | repeated string | No | Send to channels |
fcm_tokens | repeated string | No | Send to a list of FCM tokens |
fcm_topic | string | No | Send to a FCM topic |
fcm_condition | string | No | Send to a FCM condition |
hms_tokens | repeated string | No | Send to a list of HMS tokens |
hms_topic | string | No | Send to a HMS topic |
hms_condition | string | No | Send to a HMS condition |
apns_tokens | repeated string | No | Send to a list of APNs tokens |
PushNotification
:
Field | Type | Required | Description |
---|---|---|---|
fcm | FcmPushNotification | No | Notification for FCM |
hms | HmsPushNotification | No | Notification for HMS |
apns | ApnsPushNotification | No | Notification for APNs |
uid | string | No | Unique send id |
expire_at | int64 | No | Unix timestamp when Centrifugo stops attempting to send this notification (this does not relate to notification TTL fields) |
FcmPushNotification
:
Field | Type | Required | Description |
---|---|---|---|
message | JSON object | Yes | FCM Message described in FCM docs. |
HmsPushNotification
:
Field | Type | Required | Description |
---|---|---|---|
message | JSON object | Yes | HMS Message described in HMS Push Kit docs. |
ApnsPushNotification
:
Field | Type | Required | Description |
---|---|---|---|
headers | map<string, string> | No | APNs headers |
payload | JSON object | Yes | APNs payload |
send_push_notification result
Field Name | Type | Description |
---|---|---|
uid | string | Unique send id, matches uid in request if it was provided |
Metrics
Several metrics are available to monitor the state of Centrifugo push worker system:
centrifugo_push_notification_count
- counter, shows total count of push notifications sent to providers (splitted by provider, recipient type, platform, success, error code).centrifugo_push_queue_consuming_lag
- gauge, shows the lag of queues, should be close to zero most of the time. Splitted by provider and name of queue.centrifugo_push_consuming_inflight_jobs
- gauge, shows immediate number of workers proceccing pushes. Splitted by provider and name of queue.centrifugo_push_job_duration_seconds
- summary, provides insights about worker job duration timings. Splitted by provider and recipient type.
Tutorial
Coming soon.