Device Group Messaging on Android

With device group messaging, you 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.

You can use device group messaging with the Admin SDKs, or by implementing the XMPP or HTTP protocols on your app 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:

  1. Obtain registration tokens for each device you want to add to the group.

  2. 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

  1. Open your project in the Google Developers Console.
  2. From the menu at top left, select API Manager and then Credentials.
  3. Click New credentials and select OAuth Client ID.
  4. In the Create Client ID dialog, select Web Application as the application type, and click Create.
  5. 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.

Device Group 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!",
   }
}

Device Group 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"
  ]
}

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 with backoff between retries.

Device Group 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>

Device Group 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());

Send feedback about...

Need help? Visit our support page.