[[service]] provides a "mobile wake-up" function that allows a mobile application to subscribe to a data node of the [[service]] database and to be notified when data under this node is updated even if the mobile application is stopped. In this case, the application is launched or woken up.
In usual settings, when data is updated somewhere in a [[service]] database, it is shared in real time with every instance of Android app that runs in foreground on every connected device. However this operation relies on websockets, which die as soon as apps go to background.
The "mobile wake-up" function overcomes this limitation by making it possible to wake-up a stopped or background Android app upon a data update in the [[service]] database. It can also optionally forward data to it.
With this feature, you choose the path of the data node in the [[service]] database that may wake up your Android app. This path covers updates on all its child data nodes. For example, if you subscribe to the root path, every change in the database will be notified.
Subscribing and unsubscribing are done using either methods of the [[service]] Android SDK or [[service]] specific REST requests. Then the waking up process uses Firebase Cloud Messaging (FCM, formerly Google Cloud Messaging) for Android devices and Apple Push Notification service (APNs) for Apple devices.
Actually, your app asks [[service]] to listen to some data node at a given path, and as soon as something happens under this path, [[service]] asks FCM to send an appropriate message to appropriate (subscribed) devices. Your device receives this message and has to handle it. Typically you can display it to the user through a notification or launch your app so that it resynchronizes itself using [[service]] SDK API and detects what is new and what to do.
You also need to provide what we call a "device id" to allow FCM to send the message to the right device. Retrieving this device id is done through FCM API on the device itself.
Mobile wake-up developer configuration
Prerequisites
Mobile wake-up is a functionality provided by Google for Android OS (FCM) and by Apple for iOS (APNs). [[service]] interconnects only with FCM. As FCM provides a relay service to APNs, APNs can also be used via [[service]] and FCM. In order to use FCM (or APNs through the FCM relay), you need to configure a Google key in [[console]].
To get such a key, first, go to Firebase console and create a project, then generate a new private key in project settings / Service account and download it.
In addition, if you want to use APNs, you need to follow this procedure.
Using [[console]]
Go to wake-up tab in [[console]], enable wake-up functionality, and upload private key (from FCM).
Add a wake-up subscription
In order to set up wake-up subscriptions from your mobile app code, you can use either the [[service]] Android SDK API or the low-level REST API (typically for iOS apps).
In both cases, you need the "device id" of the mobile device (referred to as "token" in the official FCM API). You can get it using FCM API:
String myDeviceId = FirebaseInstanceId.getInstance().getToken();
let myDeviceId : String = InstanceID.instanceID().token()
This section covers tasks you may have completed if you have already enabled other Firebase features for your app. For FCM specifically, you'll need to upload your APNs authentication key and register for remote notifications.
Here is an example [[snippet]]:
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>/some/webcom/path");
ref.wakeupSubscribe(myDeviceId, "value", new OnComplete() {
@Override
public void onComplete() {
Log.d(TAG, " wakeupSubscribe onComplete ");
}
@Override
public void onError(final WebcomError error) {
Log.d(TAG, " wakeupSubscribe onError ", error.toException());
}
});
let ref : WCWebcom = WCWebcom(url : "file://io./base/samplechat")
let path : String = "contacts/orange/message"
ref?.wakeupSubscribe(deviceidToken: myDeviceId, tokenAuth: tokenAuth, path: path, mode: mode , completeCallback: { (data, error) in
if (error != nil){
print("wakeupSubscribe onError \(error.debugDescription) ")
}else {
print("wakeupSubscribe onComplete")
}
})
curl -X PUT "[[baseUrl]]/base/<your-app>/.wakeup/some/webcom/path?id=<myDeviceId>"
In the Android version, the path of the subscription to register is given by the path associated to the Webcom
object
reference on which the wakeupSubscribe
method is called.
The second parameter of this method is a subscription mode that controls the data to send back in future notifications.
It can be either "value"
, "noData"
(or null
, this is the default value) or "childEvent"
(see below).
The last parameter is a handler whose onComplete
callback is called asynchronously once the wake-up subscription is
successfully registered on the [[service]] server. If the registration fails on the server, then the onError
callback
is called instead.
With this method, the subscription is registered using the current authentication state maintained by the [[service]] SDK. The authentication state constraints the data nodes on which the subscriptions are allowed.
In the iOS version, the path of subscription to register is given by the params of the wakeupSubscribe method.
deviceidToken : is a DeviceID of the mobile device (referred to as "token" in the official FCM API). You can get it using FCM API.
token : An authentication token.
path : You choose the path of the data node in the Flexible Datasync database that may wake up your iOS app.
mode: is a subscription mode that controls the data to send back in future notifications. It can be either
"value"
,"noData"
(ornull
, this is the default value) or"childEvent"
(see belowcompleteCallback: Block called once Wakeup subscribe is complete. On failure, return error object (Error).
In the REST version, the sub-path after .wakeup
in the URI is the path of the [[service]] data node where the
subscription takes place.
In the query part, only the id
parameter is mandatory, which refers to the FCM device id. Other query parameters
control the [[service]] authentication state to take into account for the subscription or the data to send back in
future notifications.
Query parameter Type Mandatory
OptionalDescription token
string O An authentication token. If not specified, the subscription is done without authentication. id
string M FCM device id (referred to as "token" in Android APIs) that uniquely identifies the mobile device mode
string O Subscription mode that controls the data sent back in notifications. Supported values are: " noData
" (default value), "value
" or "childEvent
" (see below)
On success you will receive a 204 (no content) response.
On error, you will receive an error response containing a JSON message with a status
field giving the error reason
(as a string).
REST status code JSON status Description 404 namespace_does_not_exist
No [[service]] application found with this name 403 disabled
Mobile wake-up feature is disabled for this application 403 permission_denied
Security rules prevent read access to the data located at the subscribed data node (according to current data and the specified authentication token) 403 too_big
The data located at the subscribed data node is too big and can no longer be subscribed (see weight limitations)
Notes:
- data included in FCM and APNs notifications are limited to 4KB
- A wake-up subscription is uniquely identified by a 3-tuple ([[service]] application name, path, device-id).
Refresh a subscription
A subscription must be refreshed before expiration. Expiration time is configured through wake-up settings on [[console]]. To refresh a subscription, you need to send the same request than the original subscription.
If a subscription expires, an FCM message for revocation will be sent to subscribed devices with status "expired"
.
Device id (e.g. FCM token) refresh
When receiving FCM notification "onTokenRefresh", you have to
wakeupSubscribe
with new deviceId (FCM token),wakeupUnsubscribe
with former deviceId to clean it on [[service]] side.
Remove a wake-up subscription
Removing a subscription may be done like this [[snippet]]:
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>/some/webcom/path");
ref.wakeupUnsubscribe(myDeviceId, new OnComplete() {
@Override
public void onComplete() {
Log.d(TAG, " wakeup UNSubscribe onComplete ");
}
@Override
public void onError(final WebcomError error) {
Log.d(TAG, " wakeup UNSubscribe onError ", error.toException());
}
});
let ref : WCWebcom = WCWebcom(url : "file://io./base/samplechat")
let path : String = "contacts/orange/message"
ref?.wakeupUnsubscribe(deviceidToken: deviceId, tokenAuth: tokenAuth, path: path, completeCallback: { (data, error) in
if (error != nil){
print("wakeupUnsubscribe onError \(error.debugDescription) ")
}else {
print("wakeupUnsubscribe onComplete")
}
})
curl -X DELETE "[[baseUrl]]/base/<your-app>/.wakeup/some/webcom/path?id=<myDeviceId>"
In the Android version, like for adding a subscription, the path of the subscription to remove is retrieved from the
path associated to the Webcom
object reference on which the wakeupUnsubscribe
is called. This method expects as
first parameter the "device id" (it must be the same than the one used with the wakeupSubscribe
method). The second
parameter is a handler whose onComplete
callback is called asynchronously once the wake-up subscription is
successfully unregistered on the [[service]] server. If the unregistration fails on the server, then the onError
callback is called instead.
In the iOS version , like for adding a subscription, the path of subscription to register is given by param of the wakeupunSubscribe method
"device id" , "token" & "path" (it must be the same than the one used with the
wakeupSubscribe
method).completeCallback: Block called once Wakeup subscribe is complete. On failure, return error object (Error).
In the REST version, the sub-path after .wakeup
in the URI is the path of the [[service]] data node where the
subscription is unregistered. The available query parameters are:
Query parameter Type Mandatory
OptionalDescription id
string M FCM device id (referred to as "token" in Android APIs) that uniquely identifies the mobile device token
string O An authentication token, which must have the same identity than the one used for subscription. If not specified, the unsubscription is done without authentication.
Receive and parse a wake-up message (sometimes called notification)
When data is written on a path subscribed for wake-up in the [[service]] database, [[service]] sends FCM data messages to wake up your application (see documentation on FCM messages).
For more details please refer to the official FCM documentation.
In "noData
" mode
The device is just awaken and can reconnect through [[service]] API to read needed data and resynchronize.
The data payload sent by [[service]] has the following structure:
- a
t
(type) field with string value "noData
" - an
app
string field containing the [[service]] application name - an
sp
string field containing the subscription path within the [[service]] database
In "value
" mode
The data contains the complete new value of the data node at subscription path.
The data payload sent by [[service]] has the following structure:
- a
t
(type) field with string value "value
" - an
app
string field containing the [[service]] application name - an
sp
string field containing the subscription path within the [[service]] database - a
d
(userData) field with a string value that contains a JSON encoded object (due to FCM limitations) representing the current data at the subscribed path. This field may be omitted if the payload size is too big (see limitations). - an
s
(status) field whose string value can be "OK
" or "TooBig
" if the payload is too big and userData has been removed (see limitations)
In "childEvent
" mode
The data payload sent by [[service]] has the following structure:
- a
t
(type) field with string value "childEvent
" - an
app
string field containing the [[service]] application name - an
sp
string field containing the subscription path within the [[service]] database - an
s
(status) field whose string value can be "OK
" or "TooBig
" if the payload is too big and userData has been removed (see limitations) - an
added
field with a string value that contains a JSON encoded object representing the data of the added child nodes. This field may be omitted if the payload size is too big (see limitations). - a
removed
field with a string value that contains a JSON encoded array containing the keys of the removed children. This field may be omitted if the payload size is too big (see limitations). - a
changed
field with a string value that contains a JSON encoded object representing the data of the changed child nodes. This field may be omitted if the payload size is too big (see limitations).
Subscription revocation
When a subscription is revoked on the [[service]] server, a FCM data message is sent to each subscribed device with the following data payload structure:
- a
t
(type) field with string value "revoke
" - a
r
(reason) string field containing the status code of the revocation cause (see below) - an
app
string field containing the [[service]] application name - an
sp
string field containing the subscription path within the [[service]] database
Revocation causes are:
Status code Description permission_denied
Security rules prevent read access to the data located at the subscribed data node (according to current data and the specified authentication token) namespace_does_not_exist
The [[service]] application database has just been deleted disabled
Mobile wake-up feature has just been disabled for the [[service]] application expired
Subscription has expired too_big
The data located at the subscribed data node is too big and can no longer be subscribed (see weight limitations) because it would result in unreasonable performances
Size limitations
Data payload size limit
The data payload of wake-up messages is limited to 4KB on both FCM and APNs.
More precisely, the whole data payload of a wake-up message is defined by a JSON compact-serialized string. And the length of this string should not be more than 4093 bytes. For example, the following data payload is 114 bytes-long:
{"s":"OK","t":"value","app":"toto","sp":"/some/webcom/path","d":"{\"a\":\"WGj2WtQWVEjQGhQqb7r678xW3PwWmB4Z3zj\"}"}
If the length is 4064 bytes-long or more:
- in "value" mode: the status field (
s
) is set to"TooBig"
and the userData field (d
) is removed - in "childEvent" mode:
- if possible, the status field (
s
) is set to"OnlyKeys"
, bothadded
andchanged
fields contain only keys withtrue
as mapped values, - otherwise (the length of the data payload with only keys and
true
as value is 4064 bytes or more) the status field (s
) is set to"TooBig"
andadded
,removed
andchanged
fields are empty.
- if possible, the status field (
When data is missing because of payload size limitation, the only way for application to retrieve it is to invoke explicitly read functions of the [[service]] SDK API.
Subscription path length limit
Subscription path length cannot be more than 2048 bytes.
Errors when sending notification to FCM servers
In case of error returned by FCM server. If it is recoverable ("QUOTA_EXCEEDED", "UNAVAILABLE", "INTERNAL", "UNSPECIFIED_ERROR"), it is trying again with exponential backoff starting after 1 second, and during 2 hours. If after that it still fails, the current pending notifcations are discarded but the subscription remains active for future notifications.
In case of other error, the subscription is revoked, and if possible, a "revoke" notification is sent.