Enviar mensagens para grupos de dispositivos no Android

Com as mensagens para grupos de dispositivos, é possível adicionar vários dispositivos a um único grupo. Esse processo é semelhante ao das mensagens de tópico, mas inclui a autenticação para garantir que a associação ao grupo seja gerenciada apenas pelos seus servidores. Por exemplo, se você quiser enviar mensagens diferentes para diferentes modelos de smartphone, seus servidores poderão adicionar/remover registros dos respectivos grupos e enviar a mensagem relevante para cada um deles. A diferença entre as mensagens para grupos de dispositivos e as mensagens de tópico é que, no primeiro caso, o gerenciamento de grupos de dispositivos é feito a partir dos seus servidores em vez de diretamente no aplicativo.

Use mensagens de grupo de dispositivos com SDKs de administrador ou implementando protocolos XMPP ou HTTP em seu servidor de apps. O número máximo permitido de membros em uma chave de notificação é 20.

Gerenciamento de grupos de dispositivos

Antes de enviar mensagens a um grupo de dispositivos, você precisa:

  1. obter tokens de registro para cada dispositivo que você quer adicionar ao grupo;

  2. criar a notification_key, que identifica o grupo de dispositivos, mapeando um grupo particular (normalmente, um usuário) para todos os tokens de registro associados do grupo. Crie chaves de notificação no servidor do app ou em apps cliente do Android.

Normalmente, o gerenciamento básico de grupos de dispositivos (criar e remover grupos e adicionar ou remover dispositivos) é executado no servidor do app. Consulte a referência de protocolo HTTP legada para ver uma lista de chaves compatíveis.

Se preferir, apps cliente do Android podem gerenciar grupos de dispositivos no cliente.

Gerenciamento de grupos de dispositivos no servidor do app

Criação de um grupo de dispositivos

Para criar um grupo de dispositivos, envie uma solicitação POST que forneça um nome ao grupo e uma lista de tokens de registro para os dispositivos. O FCM retorna uma nova notification_key que representa o grupo de dispositivos.

Solicitação HTTP POST

Envie uma solicitação, conforme abaixo, para https://fcm.googleapis.com/fcm/notification:

https://fcm.googleapis.com/fcm/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"]
}

O notification_key_name é o nome ou o identificador (por exemplo, pode ser um nome de usuário) exclusivo para determinado grupo. O notification_key_name e a notification_key são exclusivos a um grupo de tokens de registro. Quando você tem vários apps cliente para o mesmo código do remetente, é importante que o notification_key_name seja exclusivo para cada um deles. Isso garante que as mensagens sejam direcionadas apenas para o app pretendido.

Formato da resposta

Um solicitação bem-sucedida retorna uma notification_key como abaixo:

{
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}

Salve a notification_key e o notification_key_name correspondente para usar em operações posteriores.

Como recuperar uma chave de notificação

Se for necessário recuperar uma chave de notificação, use o notification_key_name em uma solicitação GET como mostrado:

https://fcm.googleapis.com/fcm/notification?notification_key_name=appUser-Chris
Content-Type:application/json
Authorization:key=API_KEY
project_id:SENDER_ID
{}

O servidor retorna uma string codificada exclusiva para cada solicitação GET referente a um determinado nome de chave de notificação. Cada string pode parecer uma chave diferente mas, na realidade, é um valor válido de "notification_key".

Como adicionar e remover dispositivos de um grupo de dispositivos

Para adicionar ou remover dispositivos de um grupo existente, envie uma solicitação POST com o parâmetro operation definido como add ou remove e forneça os tokens de registro de adição ou remoção.

Solicitação HTTP POST

Por exemplo, para adicionar um dispositivo com o código de registro 51 para appUser-Chris, você enviaria esta solicitação:

{
   "operation": "add",
   "notification_key_name": "appUser-Chris",
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
   "registration_ids": ["51"]
}

Formato da resposta

Uma solicitação para adicionar ou remover um dispositivo retorna uma notification_key como esta:

{
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}

Como gerenciar grupos de dispositivos em apps cliente do Android

O gerenciamento de grupos de dispositivos no cliente é útil para os casos em que um servidor não está disponível. Para criar um grupo de dispositivos no cliente, o dispositivo precisa ter pelo menos uma Conta do Google. Observe que o processo de criação de uma chave de notificação no cliente é bastante diferente do processo no lado do servidor descrito acima.

Para criar um grupo de dispositivos no cliente:

Receber um ID do cliente

  1. Abra seu projeto no Google Developers Console.
  2. No menu no canto superior esquerdo, selecione APIs e serviços e, em seguida, Credenciais.
  3. Clique em Novas credenciais e selecione ID do cliente OAuth.
  4. Na caixa de diálogo Criar ID do cliente, selecione Aplicativo da Web como tipo de app e clique em Criar.
  5. Copie o valor exibido no ID do cliente. Esse valor representa o "escopo" da Conta do Google usado para gerar um idToken.

Valide a Conta do Google no dispositivo.

Quando você receber um ID do cliente do Google Developers Console, verifique se há uma Conta do Google no dispositivo.

Java
Android

// 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() {
    // This call requires the Android GET_ACCOUNTS permission
    Account[] accounts = AccountManager.get(this /* activity */).
            getAccountsByType("com.google");
    if (accounts.length == 0) {
        return null;
    }
    return accounts[0].name;
}

Kotlin
Android

// This snippet takes the simple approach of using the first returned Google account,
// but you can pick any Google account on the device.
@SuppressLint("MissingPermission")
fun getAccount(): String {
    // This call requires the Android GET_ACCOUNTS permission
    val accounts = AccountManager.get(this /* activity */).getAccountsByType("com.google")
    return if (accounts.isEmpty()) {
        ""
    } else accounts[0].name
}

Receber um token de autenticação

Em seguida, solicite um token de autenticação (idToken) usando a classe GoogleAuthUtil. Exemplo:

Java
Android

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(this, accountName, scope);
} catch (Exception e) {
    Log.w(TAG, "Exception while getting idToken: " + e);
}

Kotlin
Android

val accountName = getAccount()

// Initialize the scope using the client ID you got from the Console.
val scope = "audience:server:client_id:" +
        "1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com"

var idToken: String? = null
try {
    idToken = GoogleAuthUtil.getToken(this, accountName, scope)
} catch (e: Exception) {
    Log.w(TAG, "Exception while getting idToken: $e")
}

Adicionar ou remover dispositivos de grupos

Crie uma solicitação HTTP POST para https://fcm.googleapis.com/fcm/googlenotification para remover/adicionar tokens de registro de/para um grupo. No cabeçalho da solicitação, project_id precisa estar definido como o código do remetente e Content-Type, como JSON.

Adicionar ao grupo

Uma operação de adição requer as seguintes chaves: operation definida como add, id_token definida como o idToken obtido acima, notification_key_name e registration_ids. O userEmail variável, como mostrado abaixo, pode ser obtido a partir do valor de accounts[0].name. O cliente somente pode gerenciar os grupos mapeados a esse e-mail/conta.

Java
Android

public String addToGroup(
        String senderId, String userEmail, String registrationId, String idToken)
        throws IOException, JSONException {
    URL url = new URL("https://fcm.googleapis.com/fcm/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");
}

Kotlin
Android

@Throws(IOException::class, JSONException::class)
fun addToGroup(
    senderId: String,
    userEmail: String,
    registrationId: String,
    idToken: String
): String {
    val url = URL("https://fcm.googleapis.com/fcm/googlenotification")
    val con = url.openConnection() as HttpURLConnection
    con.doOutput = true

    // HTTP request header
    con.setRequestProperty("project_id", senderId)
    con.setRequestProperty("Content-Type", "application/json")
    con.setRequestProperty("Accept", "application/json")
    con.requestMethod = "POST"
    con.connect()

    // HTTP request
    val data = JSONObject()
    data.put("operation", "add")
    data.put("notification_key_name", userEmail)
    data.put("registration_ids", JSONArray(arrayListOf(registrationId)))
    data.put("id_token", idToken)

    val os = con.outputStream
    os.write(data.toString().toByteArray(charset("UTF-8")))
    os.close()

    // Read the response into a string
    val `is` = con.inputStream
    val responseString = Scanner(`is`, "UTF-8").useDelimiter("\\A").next()
    `is`.close()

    // Parse the JSON string and return the notification key
    val response = JSONObject(responseString)
    return response.getString("notification_key")
}

A operação bem-sucedida retorna uma notification_key. Guarde essa notification_key e o notification_key_name correspondente para usar em operações posteriores.

Remover do grupo

Uma operação de remoção requer as seguintes chaves: operation definida como remove, id_token definido como o idToken obtido acima, notification_key_name e registration_ids.

Java
Android

// 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);

Kotlin
Android

// HTTP request
val data = JSONObject()
data.put("operation", "remove")
data.put("notification_key_name", userEmail)
data.put("registration_ids", JSONArray(arrayListOf(registrationId)))
data.put("id_token", idToken)

Envio de mensagens downstream a grupos de dispositivos

Enviar mensagens para um grupo de dispositivos é bastante similar a enviar mensagens para um dispositivo individual. Defina o parâmetro to como a chave de notificação exclusiva do grupo. Consulte Tipos de mensagem para detalhes sobre suporte a payload. Nos exemplos desta página, você vê como enviar mensagens de dados para esses grupos de dispositivos nos protocolos HTTP e XMPP.

Solicitação HTTP POST para grupo de dispositivos

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

Resposta HTTP do grupo de dispositivos

Este é um exemplo de êxito na operação: a notification_key tem dois tokens de registro associados a ela e a mensagem foi enviada a ambos:

{
  "success": 2,
  "failure": 0
}

Este é um exemplo de êxito parcial na operação: a notification_key tem três tokens de registro associados a ela. A mensagem foi enviada apenas para um dos tokens de registro. A resposta lista os tokens onde houve falha ao receber a mensagem:

{
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

Quando uma mensagem não é entregue a um ou mais tokens de registro associados a uma notification_key, o servidor de apps faz uma nova tentativa com um intervalo de espera entre elas.

Se o servidor tenta enviar uma mensagem para um grupo de dispositivos que não tem membros, a resposta é parecida com esta, com 0 sucesso e 0 falha:

{
  "success": 0,
  "failure": 0
}

Mensagem XMPP para grupo de dispositivos

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

Resposta XMPP do grupo de dispositivos

Quando a mensagem é enviada com sucesso para qualquer um dos dispositivos do grupo, o servidor de conexões XMPP responde com um ACK. Quando ocorre falha no envio de todas as mensagens a todos os dispositivos do grupo, o servidor responde com um NACK.

Este é um exemplo de êxito na operação: a notification_key tem três tokens de registro associados a ela e a mensagem foi enviada a todos:

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success": 3,
  "failure": 0,
  "message_id": "m-1366082849205"
}

Este é um exemplo de êxito parcial na operação: a notification_key tem três tokens de registro associados a ela. A mensagem foi enviada apenas para um dos tokens de registro. A resposta lista os tokens onde houve falha ao receber a mensagem:

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

Quando um servidor de conexão FCM não entrega para todos os dispositivos no grupo, o servidor do app receberá uma resposta NACK.

Para ver a lista completa de opções de mensagens, consulte as informações de referência do protocolo do servidor de conexão selecionado (HTTP ou XMPP).

Envio de mensagens upstream a grupos de dispositivos

Apps cliente podem enviar mensagens upstream para grupos de dispositivos por meio de segmentação de mensagens para a chave de notificação apropriada no campo to.

Esta chamada ao FCM envia uma mensagem upstream a uma chave de notificação. O objeto consiste em pares de chave-valor.

Java
Android

String to = "a_unique_key"; // the notification key
AtomicInteger msgId = new AtomicInteger();
FirebaseMessaging.getInstance().send(new RemoteMessage.Builder(to)
        .setMessageId(String.valueOf(msgId.get()))
        .addData("hello", "world")
        .build());

Kotlin
Android

val to = "a_unique_key" // the notification key
val msgId = AtomicInteger()
FirebaseMessaging.getInstance().send(RemoteMessage.Builder(to)
        .setMessageId(msgId.get().toString())
        .addData("hello", "world")
        .build())

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.