With device group messaging, app servers can send a single message to multiple instances of an app running on devices belonging to a group. Typically, "group" refers a set of different devices that belong to a single user. All devices in a group share a common notification key, which is the token that FCM uses to fan out messages to all devices in the group.
Device group messaging makes it possible for every app instance in a group to reflect the latest messaging state. In addition to sending messages downstream to a notification key, you can enable devices to send upstream messages to a device group. You can use device group messaging with either the XMPP or HTTP connection server. The limit on data payload is 2KB when sending to iOS devices, and 4KB for other platforms.
The maximum number of members allowed for a
notification_key
is 20.
Managing device groups
Before sending messages to a device group, you must:
-
Obtain registration tokens for each device you want to add to the group.
-
Create the
notification_key
, which identifies the device group by mapping a particular group (typically a user) to all of the group's associated registration tokens. You can create notification keys on the app server or on Android client apps.
Basic management of device groups — creating and removing groups, and adding or removing devices — is usually performed via the app server. See the HTTP protocol reference for a list of supported keys.
Optionally, Android client apps can manage device groups from the client side.
Managing device groups on the app server
Creating a device group
To create a device group, send a POST request that provides a name
for the group, and a list of registration tokens for the devices.
FCM returns a new notification_key
that represents the device group.
HTTP POST request
Send a request like the following to
https://android.googleapis.com/gcm/notification
:
https://android.googleapis.com/gcm/notification Content-Type:application/json Authorization:key=API_KEY project_id:SENDER_ID { "operation": "create", "notification_key_name": "appUser-Chris", "registration_ids": ["4", "8", "15", "16", "23", "42"] }
The notification_key_name
is a name or identifier
(e.g., it can be a username) that is unique to a given group. The
notification_key_name
and
notification_key
are unique to a group of registration
tokens. It is important that notification_key_name
is
unique per client app if you have multiple client apps for the same
sender ID.
This ensures that messages only go to the intended target app.
Response format
A successful request returns a notification_key
like
the following:
{ "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ" }
Save the notification_key
and the corresponding
notification_key_name
to use in subsequent operations.
Adding and removing devices from a device group
To add or remove devices from an existing group, send a POST
request with the operation
parameter set to
add
or remove
, and provide the
registration tokens for addition or removal.
HTTP POST request
For example, to add a device with the registration ID 51 to appUser-Chris, you would send this request:
{
"operation": "add",
"notification_key_name": "appUser-Chris",
"notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
"registration_ids": ["51"]
}
Response format
A successful request to either add or remove a device returns a
notification_key
like the following:
{ "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ" }
Managing device groups on Android client apps
Managing device groups on the client is useful for cases where a server is unavailable. To create a device group on the client, the device must have at least one Google account. Note that the process for creating a notification key on the client is significantly different from the server-side process described above.
To create a device group on the client:
Obtain a Client ID
- Open your project in the Google Developers Console.
- From the
menu at top left, select API Manager and then Credentials.
- Click New credentials and select OAuth Client ID.
- In the Create Client ID dialog, select Web Application as the application type, and click Create.
- Copy the value displayed for the Client ID. This client ID
represents a Google account "scope" that you will use to generate
an
idToken
.
Validate the Google account on the device
Once you've obtained a client ID from Google Developers Console, check the device for the presence of a Google account.
// This snippet takes the simple approach of using the first returned Google account, // but you can pick any Google account on the device. public String getAccount() { Account[] accounts = AccountManager.get(getActivity()). getAccountsByType("com.google"); if (accounts.length == 0) { return null; } return accounts[0].name; }
Get an authentication token
Next, get an authentication token (idToken
) by using
the
GoogleAuthUtil
class. For example:
String accountName = getAccount(); // Initialize the scope using the client ID you got from the Console. final String scope = "audience:server:client_id:" + "1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com"; String idToken = null; try { idToken = GoogleAuthUtil.getToken(context, accountName, scope); } catch (Exception e) { log("exception while getting idToken: " + e); } ...
Add or remove devices from groups
Build an HTTP POST request to https://android.googleapis.com/gcm/googlenotification
to add/remove registration tokens to/from a group. The request
header needs to have project_id
set to the sender ID and
Content-Type
set to JSON.
Add to group
An add operation requires the following keys:
operation
set to add
,
id_token
set to the idToken
obtained
above, notification_key_name
and
registration_ids
. The userEmail
variable,
as shown below, can be derived from the value of
accounts[0].name
. The client is authorized to manage
only groups mapped to this email/account.
public String addNotificationKey( String senderId, String userEmail, String registrationId, String idToken) throws IOException, JSONException { URL url = new URL("https://android.googleapis.com/gcm/googlenotification"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setDoOutput(true); // HTTP request header con.setRequestProperty("project_id", senderId); con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Accept", "application/json"); con.setRequestMethod("POST"); con.connect(); // HTTP request JSONObject data = new JSONObject(); data.put("operation", "add"); data.put("notification_key_name", userEmail); data.put("registration_ids", new JSONArray(Arrays.asList(registrationId))); data.put("id_token", idToken); OutputStream os = con.getOutputStream(); os.write(data.toString().getBytes("UTF-8")); os.close(); // Read the response into a string InputStream is = con.getInputStream(); String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next(); is.close(); // Parse the JSON string and return the notification key JSONObject response = new JSONObject(responseString); return response.getString("notification_key"); }
A successful operation returns a notification_key
.
Save this notification_key
and the corresponding
notification_key_name
to use in subsequent operations.
Remove from group
A remove operation requires the following keys:
operation
set to remove
,
id_token
set to the idToken
obtained
above, notification_key_name
and
registration_ids
.
// HTTP request JSONObject data = new JSONObject(); data.put("operation", "remove"); data.put("notification_key_name", userEmail); data.put("registration_ids", new JSONArray(Arrays.asList(registrationId))); data.put("id_token", idToken);
Sending downstream messages to device groups
Sending messages to a device group is very similar to sending
messages to an individual device. Set the to
parameter
to the unique notification key for the device group. See
Message types for details on
payload support. Examples in this page show how to send data
messages to device groups in HTTP and XMPP protocols.
HTTP POST Request
https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA { "to": "aUniqueKey", "data": { "hello": "This is a Firebase Cloud Messaging Device Group Message!", } }
HTTP Response
Here is an example of "success"— the notification_key
has 2 registration tokens associated with it, and the message was
successfully sent to both of them:
{ "success": 2, "failure": 0 }
Here is an example of "partial success" — the
notification_key
has 3 registration tokens associated
with it. The message was successfully sent to 1 of the registration
tokens only. The response message lists the registration tokens
that failed to receive the message:
{ "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] }
In the case of failure, the response has HTTP code 503 and no JSON
body. When a message fails to be delivered to one or more of the
registration tokens associated with a
notification_key
, the app server should retry.
XMPP Message
<message id=""> <gcm xmlns="google:mobile:data"> { "to": "aUniqueKey", "message_id": "m-1366082849205" , "data": { "hello":"This is a Firebase Cloud Messaging Device Group Message!" } } </gcm> </message>
XMPP Response
When the message is sent to any one of the devices in the group successfully, the XMPP connection server responds with an ACK. If all messages sent to all devices in the group fail, XMPP connection server responds with a NACK.
Here is an example of "success" — the notification_key
has 3 registration tokens associated with it, and the message was
successfully sent to all of them:
{ "from": "aUniqueKey", "message_type": "ack", "success": 3, "failure": 0, "message_id": "m-1366082849205" }
Here is an example of "partial success" — the
notification_key
has 3 registration tokens associated
with it. The message was successfully sent to 1 of the registration
tokens only. The response message lists the registration tokens
that failed to receive the message:
{ "from": "aUniqueKey", "message_type": "ack", "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] }
When FCM connection server fails to deliver to all devices in the group. App server will receive a nack response.
For the full list of message options, see the reference information for your chosen connection server protocol, HTTP or XMPP.
Sending upstream messages to device groups
Client apps can send messages upstream to device groups by
targeting messages to the appropriate notification key in the
to
field.
The following call to FCM sends an upstream message to a notification key. The object consists of key-value pairs.
FirebaseMessaging fm = FirebaseMessaging.getInstance(); String to = aUniqueKey; // the notification key AtomicInteger msgId = new AtomicInteger(); fm.send(new RemoteMessage.Builder(to) .setMessageId(msgId) .addData("hello", "world") .build());