Ir a la consola

Envía mensajes a grupos de dispositivos en Android

Los mensajes por grupos de dispositivos te permiten agregar varios dispositivos a un solo grupo. Esta función es parecida a la mensajería por temas, pero incluye autenticación para garantizar que solo tus servidores puedan administrar la membresía de los grupos. Por ejemplo, si quieres enviar mensajes distintos según el modelo de teléfono, tus servidores pueden agregar registros a los grupos correspondientes o quitarlos de ellos, y enviar el mensaje adecuado a cada grupo. La diferencia entre los mensajes por grupos de dispositivos y la mensajería por temas es que los primeros requieren administrar los grupos de dispositivos en tus servidores en lugar de en tu aplicación de manera directa.

Puedes usar los mensajes grupales de dispositivos con los protocolos heredados XMPP o HTTP en tu servidor de apps. El SDK de Firebase Admin para Node.js está basado en los protocolos heredados y también proporciona funciones de mensajes a grupos de dispositivos. La cantidad máxima de miembros permitida para una clave de notificación es de 20.

Administra grupos de dispositivos

Antes de enviar mensajes a un grupo de dispositivos, debes:

  1. Obtener los tokens de registro de cada dispositivo que desees agregar al grupo.

  2. Crear la notification_key, que identifica el grupo de dispositivos mediante la asignación de un grupo específico (por lo general, un usuario) a todos los tokens de registro relacionados del grupo. Puedes crear claves de notificación en el servidor de apps o en las apps cliente de Android.

La administración básica de grupos de dispositivos (crear y quitar grupos y agregar o quitar dispositivos) se ejecuta comúnmente a través del servidor de apps. Consulta la referencia heredada del protocolo HTTP para ver una lista de claves compatibles.

De manera opcional, las apps cliente de Android pueden administrar grupos de dispositivos desde el cliente.

Administra grupos de dispositivos en el servidor de apps

Crea un grupo de dispositivos

Para crear un grupo de dispositivos, envía una solicitud POST que proporcione un nombre para el grupo y una lista de tokens de registro para los dispositivos. FCM muestra una notification_key nueva que representa al grupo de dispositivos.

Solicitud HTTP POST

Envía una solicitud como la siguiente a 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"]
}

El notification_key_name es un nombre o identificador (p. ej., puede ser un nombre de usuario) que es único para un grupo determinado. El notification_key_name y la notification_key son únicos en un grupo de tokens de registro. Si tienes varias apps cliente para el mismo notification_key_name, es importante que notification_key_name sea único en cada una. Esto garantiza que los mensajes se envíen solo a la app de destino correcta.

Formato de respuesta

Una solicitud correcta muestra una notification_key como la siguiente:

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

Guarda la notification_key y el notification_key_name correspondiente para usarlos en otras operaciones.

Recupera una clave de notificación

Si necesitas recuperar una clave de notificación existente, usa notification_key_name en una solicitud GET de la siguiente manera:

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

Para cada solicitud GET de un nombre de clave de notificación determinado, el servidor muestra una string codificada única. Si bien cada string puede parecer una clave diferente, en realidad es un valor válido para "notification_key".

Agrega y quita dispositivos desde un grupo de dispositivos

Para agregar o quitar dispositivos desde un grupo existente, envía una solicitud POST con los valores add o remove en el parámetro operation y proporciona los tokens de registro para agregarlos o quitarlos.

Solicitud HTTP POST

Por ejemplo, para agregar un dispositivo con el ID de registro 51 a appUser-Chris, debes enviar esta solicitud:

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

Formato de respuesta

Una solicitud correcta para agregar o quitar un dispositivo muestra una notification_key como la siguiente:

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

Administra grupos de dispositivos en apps cliente para Android

Administrar grupos de dispositivos en el cliente es útil para los casos en los que un servidor no está disponible. Para crear un grupo de dispositivos en el cliente, el dispositivo debe tener, al menos, una cuenta de Google. Ten en cuenta que el proceso para crear una clave de notificación en el cliente es bastante diferente del proceso en el servidor descrito anteriormente.

Para crear un grupo de dispositivos en el cliente:

Obtén un ID de cliente

  1. Abre tu proyecto en Google Developers Console.
  2. En el menú  de la parte superior izquierda, selecciona API y servicios y, luego, Credenciales.
  3. Haz clic en Nuevas credenciales y selecciona ID de cliente de OAuth.
  4. En el diálogo Crear ID de cliente, selecciona Aplicación web como el tipo de aplicación y haz clic en Crear.
  5. Copia el valor que se muestra para el ID de cliente. Este ID de cliente representa un alcance de la cuenta de Google que usarás para generar un idToken.

Valida la cuenta de Google en el dispositivo

Una vez que obtengas un ID de cliente de Google Developers Console, revisa el dispositivo para ver si hay una Cuenta de Google.

Java

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

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

Obtén un token de autenticación

A continuación, obtén un token de autenticación (idToken) mediante la clase  GoogleAuthUtil. Por ejemplo:

Java

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

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")
}

Agrega o quita dispositivos de los grupos

Compila una solicitud HTTP POST a https://fcm.googleapis.com/fcm/googlenotification para agregar o quitar tokens de registro de un grupo. El encabezado de la solicitud debe tener el project_id con el valor del ID de remitente y el Content-Type con el valor JSON.

Agrega al grupo

Una operación de agregar debe tener las siguientes claves: operation con el valor add, id_token con el valor de idToken que se obtuvo previamente, notification_key_name y registration_ids. La variable userEmail, como se muestra a continuación, se puede derivar del valor de accounts[0].name. El cliente está autorizado para administrar solo grupos asignados a este correo electrónico o a esta cuenta.

Java

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

@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")
}

Si la operación es correcta, se obtiene una notification_key. Guarda la notification_key y el notification_key_name correspondiente para usarlos en otras operaciones.

Quita del grupo

Una operación de eliminación debe tener las siguientes claves: operation con el valor remove, id_token con el valor de idToken que se obtuvo previamente, notification_key_name y registration_ids.

Java

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

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

Envía mensajes descendentes a grupos de dispositivos

Enviar mensajes a un grupo de dispositivos es muy similar a enviar mensajes a un dispositivo individual. Establece el parámetro to como la clave de notificación única para el grupo de dispositivos. Consulta los tipos de mensaje para conocer los detalles de la compatibilidad de cargas útiles. Los ejemplos en esta página muestran cómo enviar mensajes de datos a grupos de dispositivos en protocolos HTTP y XMPP.

Solicitud HTTP POST del 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!",
   }
}

Respuesta HTTP del grupo de dispositivos

A continuación, se muestra un ejemplo de un resultado correcto: notification_key tiene 2 tokens de registro asociados y el mensaje se envió correctamente a ambos:

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

A continuación, se muestra un ejemplo de un resultado parcialmente correcto: notification_key tiene 3 tokens de registro asociados. El mensaje se envió correctamente a solo 1 de los tokens de registro. El mensaje de respuesta muestra una lista de los tokens de registro que no recibieron el mensaje:

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

Cuando un mensaje no se puede entregar a uno o más tokens de registro asociados con una notification_key, el servidor de apps debe volver a intentar la operación tras esperar un período de retirada.

Si el servidor intenta enviar un mensaje a un grupo de dispositivos que no tiene miembros, la respuesta luce como el siguiente ejemplo, con 0 resultados correctos y 0 errores:

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

Mensaje XMPP del 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>

Respuesta XMPP del grupo de dispositivos

Cuando un mensaje se envía correctamente a cualquiera de los dispositivos del grupo, el servidor de conexiones XMPP responde con un ACK. Si todos los mensajes enviados a todos los dispositivos del grupo fallan, el servidor de conexiones XMPP responde con un NACK.

A continuación, se muestra un ejemplo de un resultado correcto: notification_key tiene 3 tokens de registro asociados y el mensaje se envió correctamente a todos ellos.

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

A continuación, se muestra un ejemplo de un resultado parcialmente correcto: notification_key tiene 3 tokens de registro asociados. El mensaje se envió correctamente a solo 1 de los tokens de registro. El mensaje de respuesta muestra una lista de los tokens de registro que no recibieron el mensaje:

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

Cuando el servidor de conexiones de FCM no puede entregar el mensaje a todos los dispositivos del grupo, el servidor de apps recibe una respuesta NACK.

Para ver la lista completa de opciones de mensaje, consulta la información de referencia del protocolo de servidor de conexiones que seleccionaste, HTTP o XMPP.

Envía mensajes ascendentes a grupos de dispositivos

Las apps cliente pueden enviar mensajes ascendentes a grupos de dispositivos. Para hacerlo, deben dirigir los mensajes a la clave de notificación apropiada en el campo to.

La siguiente llamada a FCM envía un mensaje ascendente a una clave de notificación. El objeto contiene pares clave-valor.

Java

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

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