Crea solicitudes de envío del servidor de apps

Con los protocolos del servidor de apps de Firebase Admin SDK o FCM, puedes compilar solicitudes de mensajes y enviarlas a estos tipos de destinos:

  • Nombre del tema
  • Condición
  • Token de registro del dispositivo
  • Nombre del grupo de dispositivos (solo protocolo)

Puedes enviar mensajes con una carga útil de notificación compuesta por campos predefinidos, una carga útil de datos de tus propios campos definidos por el usuario o un mensaje que contenga ambas cargas útiles. Consulta Tipos de mensajes para obtener más información.

En los ejemplos de esta página, se muestra cómo enviar mensajes de notificación con el Firebase Admin SDK (que es compatible con Node, Java, Python, C#, y Go) y el protocolo de HTTP v1. También hay orientación para enviar mensajes a través de los protocolos HTTP y XMPP heredados obsoletos.

Envía mensajes a dispositivos específicos

Para enviar mensajes a un dispositivo específico, pasa su token de registro como en los siguientes ejemplos. Consulta la información de configuración del cliente para tu plataforma si deseas obtener más información sobre los tokens de registro.

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'YOUR_REGISTRATION_TOKEN';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  token: registrationToken
};

// Send a message to the device corresponding to the provided
// registration token.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// This registration token comes from the client FCM SDKs.
String registrationToken = "YOUR_REGISTRATION_TOKEN";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setToken(registrationToken)
    .build();

// Send a message to the device corresponding to the provided
// registration token.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# This registration token comes from the client FCM SDKs.
registration_token = 'YOUR_REGISTRATION_TOKEN'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    token=registration_token,
)

# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// Obtain a messaging.Client from the App.
ctx := context.Background()
client, err := app.Messaging(ctx)
if err != nil {
	log.Fatalf("error getting Messaging client: %v\n", err)
}

// This registration token comes from the client FCM SDKs.
registrationToken := "YOUR_REGISTRATION_TOKEN"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Token: registrationToken,
}

// Send a message to the device corresponding to the provided
// registration token.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// This registration token comes from the client FCM SDKs.
var registrationToken = "YOUR_REGISTRATION_TOKEN";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Token = registrationToken,
};

// Send a message to the device corresponding to the provided
// registration token.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

{
   "message":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

Comando de cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message":{
   "notification":{
     "title":"FCM Message",
     "body":"This is an FCM Message"
   },
   "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Cuando el proceso finaliza correctamente, cada método de envío muestra un ID de mensaje. El Firebase Admin SDK muestra la cadena de ID en el formato projects/{project_id}/messages/{message_id}. La respuesta del protocolo de HTTP es una clave JSON:

    {
      "name":"projects/myproject-b5ae1/messages/0:1500415314455276%31bd1c9631bd1c96"
    }

Envía mensajes a varios dispositivos

Las APIs de Admin de FCM te permiten realizar la multidifusión de un mensaje a una lista de tokens de registro de dispositivos. Puedes especificar hasta 500 tokens por invocación.

Node.js

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // …
  'YOUR_REGISTRATION_TOKEN_N',
];

const message = {
  data: {score: '850', time: '2:45'},
  tokens: registrationTokens,
};

getMessaging().sendMulticast(message)
  .then((response) => {
    console.log(response.successCount + ' messages were sent successfully');
  });

Java

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

MulticastMessage message = MulticastMessage.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .addAllTokens(registrationTokens)
    .build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
// See the BatchResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " messages were sent successfully");

Python

# Create a list containing up to 500 registration tokens.
# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_N',
]

message = messaging.MulticastMessage(
    data={'score': '850', 'time': '2:45'},
    tokens=registration_tokens,
)
response = messaging.send_multicast(message)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))

Go

// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Tokens: registrationTokens,
}

br, err := client.SendMulticast(context.Background(), message)
if err != nil {
	log.Fatalln(err)
}

// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)

C#

// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
    Tokens = registrationTokens,
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

El valor que se muestra es una lista de tokens que corresponde al orden de los tokens de entrada. Es útil cuando quieres verificar los tokens que generaron errores.

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // …
  'YOUR_REGISTRATION_TOKEN_N',
];

const message = {
  data: {score: '850', time: '2:45'},
  tokens: registrationTokens,
};

getMessaging().sendMulticast(message)
  .then((response) => {
    if (response.failureCount > 0) {
      const failedTokens = [];
      response.responses.forEach((resp, idx) => {
        if (!resp.success) {
          failedTokens.push(registrationTokens[idx]);
        }
      });
      console.log('List of tokens that caused failures: ' + failedTokens);
    }
  });

Java

// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

MulticastMessage message = MulticastMessage.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .addAllTokens(registrationTokens)
    .build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
if (response.getFailureCount() > 0) {
  List<SendResponse> responses = response.getResponses();
  List<String> failedTokens = new ArrayList<>();
  for (int i = 0; i < responses.size(); i++) {
    if (!responses.get(i).isSuccessful()) {
      // The order of responses corresponds to the order of the registration tokens.
      failedTokens.add(registrationTokens.get(i));
    }
  }

  System.out.println("List of tokens that caused failures: " + failedTokens);
}

Python

# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_N',
]

message = messaging.MulticastMessage(
    data={'score': '850', 'time': '2:45'},
    tokens=registration_tokens,
)
response = messaging.send_multicast(message)
if response.failure_count > 0:
    responses = response.responses
    failed_tokens = []
    for idx, resp in enumerate(responses):
        if not resp.success:
            # The order of responses corresponds to the order of the registration tokens.
            failed_tokens.append(registration_tokens[idx])
    print('List of tokens that caused failures: {0}'.format(failed_tokens))

Go

// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Tokens: registrationTokens,
}

br, err := client.SendMulticast(context.Background(), message)
if err != nil {
	log.Fatalln(err)
}

if br.FailureCount > 0 {
	var failedTokens []string
	for idx, resp := range br.Responses {
		if !resp.Success {
			// The order of responses corresponds to the order of the registration tokens.
			failedTokens = append(failedTokens, registrationTokens[idx])
		}
	}

	fmt.Printf("List of tokens that caused failures: %v\n", failedTokens)
}

C#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
    Tokens = registrationTokens,
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
if (response.FailureCount > 0)
{
    var failedTokens = new List<string>();
    for (var i = 0; i < response.Responses.Count; i++)
    {
        if (!response.Responses[i].IsSuccess)
        {
            // The order of responses corresponds to the order of the registration tokens.
            failedTokens.Add(registrationTokens[i]);
        }
    }

    Console.WriteLine($"List of tokens that caused failures: {failedTokens}");
}

Envía mensajes a temas

Puedes enviar mensajes al tema después de haber creado uno, ya sea mediante la suscripción de instancias de la app cliente al tema desde el cliente o a través de la API del servidor. Si es la primera vez que creas solicitudes de envío para FCM, consulta la guía sobre tu entorno de servidor y FCM para obtener información importante de carácter general y sobre la configuración.

Especifica el nombre que quieres darle al tema en la lógica de envío del backend, como se muestra a continuación:

Node.js

// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';

const message = {
  data: {
    score: '850',
    time: '2:45'
  },
  topic: topic
};

// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";

// See documentation on defining a message payload.
Message message = Message.builder()
    .putData("score", "850")
    .putData("time", "2:45")
    .setTopic(topic)
    .build();

// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    topic=topic,
)

# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Topic: topic,
}

// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";

// See documentation on defining a message payload.
var message = new Message()
{
    Data = new Dictionary<string, string>()
    {
        { "score", "850" },
        { "time", "2:45" },
    },
    Topic = topic,
};

// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message"
      }
   }
}

Comando de cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "message": {
    "topic" : "foo-bar",
    "notification": {
      "body": "This is a Firebase Cloud Messaging Topic Message!",
      "title": "FCM Message"
    }
  }
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Para enviar un mensaje a una combinación de temas, debes especificar una condición, es decir, una expresión booleana en la que se especifican los temas de destino. Por ejemplo, la siguiente condición enviará mensajes a los dispositivos suscritos a TopicA, y a TopicB o TopicC:

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

En primer lugar, FCM evalúa las condiciones en paréntesis y, luego, evalúa la expresión de izquierda a derecha. En la expresión anterior, un usuario suscrito a uno solo de los temas no recibirá el mensaje. Asimismo, un usuario que no está suscrito a TopicA no recibirá el mensaje. Las siguientes combinaciones sí lo reciben:

  • TopicA y TopicB
  • TopicA y TopicC

Puedes incluir hasta cinco temas en tu expresión condicional.

Para enviar mensajes a una condición, haz lo siguiente:

Node.js

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';

// See documentation on defining a message payload.
const message = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  condition: condition
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setCondition(condition)
    .build();

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);

Python

# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"

# See documentation on defining a message payload.
message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    condition=condition,
)

# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)

Go

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"

// See documentation on defining a message payload.
message := &messaging.Message{
	Data: map[string]string{
		"score": "850",
		"time":  "2:45",
	},
	Condition: condition,
}

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
	log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)

C#

// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";

// See documentation on defining a message payload.
var message = new Message()
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Condition = condition,
};

// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
   "message":{
    "condition": "'dogs' in topics || 'cats' in topics",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
    }
  }
}

Comando de cURL:

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "condition": "'dogs' in topics || 'cats' in topics"
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Envía mensajes a grupos de dispositivos

Para enviar mensajes a grupos de dispositivos, usa la API de HTTP v1. Si actualmente envías mensajes a grupos de dispositivos que usan las APIs de envío heredadas obsoletas para HTTP o XMPP, o cualquiera de las versiones anteriores del Firebase Admin SDK para Node.js según los protocolos heredados, te recomendamos que migres a la API de HTTP v1 lo antes posible. Las APIs de envío heredadas se inhabilitarán y quitarán en junio de 2024.

El proceso para enviar mensajes a un grupo de dispositivos es muy similar al que se usa para enviar mensajes a un dispositivo individual, mediante el mismo método que permite autorizar solicitudes de envío. Establece el campo token en la clave de notificación del grupo:

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

{
   "message":{
      "token":"APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
      "data":{
        "hello": "This is a Firebase Cloud Messaging device group message!"
      }
   }
}

Comando cURL

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message":{
   "data":{
     "hello": "This is a Firebase Cloud Messaging device group message!"
   },
   "token":"APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Envía un lote de mensajes

Los SDK de Admin admiten el envío de lotes de mensajes. Puedes agrupar hasta 500 mensajes en un solo lote y enviarlos en una sola llamada a la API con una mejora significativa en el rendimiento en comparación con el envío por separado de las solicitudes HTTP por mensaje.

Se puede usar esta función para crear un conjunto personalizado de mensajes y enviarlos a diferentes destinatarios, incluidos los temas o tokens específicos de registro de dispositivos. Usa esta función cuando, por ejemplo, necesites enviar mensajes simultáneamente a públicos distintos con algunos detalles diferentes en el cuerpo del mensaje.

Node.js

// Create a list containing up to 500 messages.
const messages = [];
messages.push({
  notification: { title: 'Price drop', body: '5% off all electronics' },
  token: registrationToken,
});
messages.push({
  notification: { title: 'Price drop', body: '2% off all books' },
  topic: 'readers-club',
});

getMessaging().sendAll(messages)
  .then((response) => {
    console.log(response.successCount + ' messages were sent successfully');
  });

Java

// Create a list containing up to 500 messages.
List<Message> messages = Arrays.asList(
    Message.builder()
        .setNotification(Notification.builder()
            .setTitle("Price drop")
            .setBody("5% off all electronics")
            .build())
        .setToken(registrationToken)
        .build(),
    // ...
    Message.builder()
        .setNotification(Notification.builder()
            .setTitle("Price drop")
            .setBody("2% off all books")
            .build())
        .setTopic("readers-club")
        .build()
);

BatchResponse response = FirebaseMessaging.getInstance().sendAll(messages);
// See the BatchResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " messages were sent successfully");

Python

# Create a list containing up to 500 messages.
messages = [
    messaging.Message(
        notification=messaging.Notification('Price drop', '5% off all electronics'),
        token=registration_token,
    ),
    # ...
    messaging.Message(
        notification=messaging.Notification('Price drop', '2% off all books'),
        topic='readers-club',
    ),
]

response = messaging.send_all(messages)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))

Go

// Create a list containing up to 500 messages.
messages := []*messaging.Message{
	{
		Notification: &messaging.Notification{
			Title: "Price drop",
			Body:  "5% off all electronics",
		},
		Token: registrationToken,
	},
	{
		Notification: &messaging.Notification{
			Title: "Price drop",
			Body:  "2% off all books",
		},
		Topic: "readers-club",
	},
}

br, err := client.SendAll(context.Background(), messages)
if err != nil {
	log.Fatalln(err)
}

// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)

C#

// Create a list containing up to 500 messages.
var messages = new List<Message>()
{
    new Message()
    {
        Notification = new Notification()
        {
            Title = "Price drop",
            Body = "5% off all electronics",
        },
        Token = registrationToken,
    },
    new Message()
    {
        Notification = new Notification()
        {
            Title = "Price drop",
            Body = "2% off all books",
        },
        Topic = "readers-club",
    },
};

var response = await FirebaseMessaging.DefaultInstance.SendEachAsync(messages);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");

Envía mensajes directos con el inicio habilitado (solo para Android)

Puedes enviar mensajes a dispositivos con el modo de inicio directo mediante HTTP v1 o las API de HTTP heredadas. Antes de enviar mensajes a dispositivos de clientes en modo de inicio directo, asegúrate de haber completado los pasos para que reciban mensajes de FCM en modo de inicio.

Envía mensajes mediante la API de HTTP v1 de FCM

La solicitud de mensaje debe incluir la clave "direct_boot_ok" : true en las opciones AndroidConfig del cuerpo de la solicitud. Por ejemplo:

https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send
Content-Type:application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

{
  "message":{
    "token" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
    "data": {
      "score": "5x1",
      "time": "15:10"
    },
    "android": {
      "direct_boot_ok": true,
    },
}

Envía mensajes mediante la API de HTTP heredada de FCM

La solicitud de mensaje debe incluir la clave "direct_boot_ok" : true en el nivel superior del cuerpo de la solicitud. Por ejemplo:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  "direct_boot_ok" : true
}

Las apps de los dispositivos que se encuentran en el modo de inicio directo (y cuando no están en ese modo) pueden controlar los mensajes que se envían con esta clave en el cuerpo de la solicitud.

Personaliza los mensajes en diferentes plataformas

El Firebase Admin SDK y el protocolo de HTTP v1 de FCM te permiten configurar todos los campos disponibles del objeto message de las solicitudes de mensajes. Esto incluye lo siguiente:

  • un conjunto común de campos que pueden interpretar todas las instancias de la app que reciben el mensaje
  • conjuntos de campos específicos de la plataforma, como AndroidConfig y WebpushConfig, que solo las instancias de la app que se ejecutan en la plataforma específica pueden interpretar

Los bloques específicos de la plataforma brindan la flexibilidad de personalizar mensajes para diferentes plataformas a fin de garantizar que se manejen correctamente cuando se reciben. El backend de FCM tendrá en cuenta todos los parámetros especificados y personalizará el mensaje para cada plataforma.

Cuándo usar campos comunes

Usa campos comunes en las siguientes circunstancias:

  • Cuando quieras segmentar las instancias de la app a todas las plataformas: Apple, Android y la Web
  • Cuando quieras enviar mensajes a temas

Todas las instancias de la app, independientemente de la plataforma, pueden interpretar los siguientes campos comunes:

Cuándo usar campos específicos de la plataforma

Usa campos específicos de la plataforma en las siguientes circunstancias:

  • Cuando quieras enviar campos solo a plataformas específicas
  • Cuando quieras enviar campos específicos de la plataforma además de campos comunes

Cuando desees enviar valores solo a plataformas específicas, no uses campos comunes, utiliza campos específicos de la plataforma en su lugar. Por ejemplo, para enviar una notificación solo a plataformas de Apple y a la Web, pero no a Android, debes usar dos conjuntos independientes de campos: uno para Apple y otro para la Web.

Cuando envíes mensajes con opciones de entrega específicas, usa campos específicos de la plataforma para configurarlas. Puedes especificar valores diferentes por plataforma si lo deseas. Sin embargo, debes usar campos específicos de la plataforma incluso cuando quieras configurar el mismo valor en distintas plataformas. Esto se debe a que cada plataforma puede interpretar el valor de manera levemente distinta. Por ejemplo, en Android, el tiempo de actividad se configura como un tiempo de vencimiento expresado en segundos, mientras que, en Apple, se configura como una fecha de vencimiento.

Ejemplo: Mensaje de notificación con opciones de ícono y color

En esta solicitud de envío, se envía un mismo título y contenido de notificación a todas las plataformas, pero también se envían algunas anulaciones específicas de la plataforma a los dispositivos Android.

Para Android la solicitud establece un ícono y un color especiales que aparecerán en estos dispositivos. Como se mencionó en la referencia de AndroidNotification, el color se especifica en formato #rrggbb y la imagen debe ser un recurso de ícono de elemento de diseño local en la app para Android.

Esta es una aproximación del efecto visual en el dispositivo de un usuario:

Dibujo simple de dos dispositivos, uno muestra un ícono y un color personalizados

Node.js

const topicName = 'industry-tech';

const message = {
  notification: {
    title: '`$FooCorp` up 1.43% on the day',
    body: 'FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  android: {
    notification: {
      icon: 'stock_ticker_update',
      color: '#7e55c3'
    }
  },
  topic: topicName,
};

getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Java

Message message = Message.builder()
    .setNotification(Notification.builder()
        .setTitle("$GOOG up 1.43% on the day")
        .setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
        .build())
    .setAndroidConfig(AndroidConfig.builder()
        .setTtl(3600 * 1000)
        .setNotification(AndroidNotification.builder()
            .setIcon("stock_ticker_update")
            .setColor("#f45342")
            .build())
        .build())
    .setApnsConfig(ApnsConfig.builder()
        .setAps(Aps.builder()
            .setBadge(42)
            .build())
        .build())
    .setTopic("industry-tech")
    .build();

Python

message = messaging.Message(
    notification=messaging.Notification(
        title='$GOOG up 1.43% on the day',
        body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    ),
    android=messaging.AndroidConfig(
        ttl=datetime.timedelta(seconds=3600),
        priority='normal',
        notification=messaging.AndroidNotification(
            icon='stock_ticker_update',
            color='#f45342'
        ),
    ),
    apns=messaging.APNSConfig(
        payload=messaging.APNSPayload(
            aps=messaging.Aps(badge=42),
        ),
    ),
    topic='industry-tech',
)

Go

oneHour := time.Duration(1) * time.Hour
badge := 42
message := &messaging.Message{
	Notification: &messaging.Notification{
		Title: "$GOOG up 1.43% on the day",
		Body:  "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
	},
	Android: &messaging.AndroidConfig{
		TTL: &oneHour,
		Notification: &messaging.AndroidNotification{
			Icon:  "stock_ticker_update",
			Color: "#f45342",
		},
	},
	APNS: &messaging.APNSConfig{
		Payload: &messaging.APNSPayload{
			Aps: &messaging.Aps{
				Badge: &badge,
			},
		},
	},
	Topic: "industry-tech",
}

C#

var message = new Message
{
    Notification = new Notification()
    {
        Title = "$GOOG up 1.43% on the day",
        Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
    },
    Android = new AndroidConfig()
    {
        TimeToLive = TimeSpan.FromHours(1),
        Notification = new AndroidNotification()
        {
            Icon = "stock_ticker_update",
            Color = "#f45342",
        },
    },
    Apns = new ApnsConfig()
    {
        Aps = new Aps()
        {
            Badge = 42,
        },
    },
    Topic = "industry-tech",
};

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
     "topic":"industry-tech",
     "notification":{
       "title":"`$FooCorp` up 1.43% on the day",
       "body":"FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day."
     },
     "android":{
       "notification":{
         "icon":"stock_ticker_update",
         "color":"#7e55c3"
       }
     }
   }
 }

Consulta la documentación de referencia de HTTP v1 para obtener información detallada sobre las claves disponibles en los bloques específicos de la plataforma del cuerpo del mensaje.

Ejemplo: Mensaje de notificación con una imagen personalizada

En el siguiente ejemplo de solicitud de envío, se envía tanto el título de notificación común a todas las plataformas como una imagen. Esta es una aproximación del efecto visual en el dispositivo de un usuario:

Dibujo simple de una imagen en una notificación en pantalla

Node.js

const topicName = 'industry-tech';

const message = {
  notification: {
    title: 'Sparky says hello!'
  },
  android: {
    notification: {
      imageUrl: 'https://foo.bar.pizza-monster.png'
    }
  },
  apns: {
    payload: {
      aps: {
        'mutable-content': 1
      }
    },
    fcm_options: {
      image: 'https://foo.bar.pizza-monster.png'
    }
  },
  webpush: {
    headers: {
      image: 'https://foo.bar.pizza-monster.png'
    }
  },
  topic: topicName,
};

getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
     "topic":"industry-tech",
     "notification":{
       "title":"Sparky says hello!",
     },
     "android":{
       "notification":{
         "image":"https://foo.bar/pizza-monster.png"
       }
     },
     "apns":{
       "payload":{
         "aps":{
           "mutable-content":1
         }
       },
       "fcm_options": {
           "image":"https://foo.bar/pizza-monster.png"
       }
     },
     "webpush":{
       "headers":{
         "image":"https://foo.bar/pizza-monster.png"
       }
     }
   }
 }

Consulta la documentación de referencia de HTTP v1 para obtener información detallada sobre las claves disponibles en los bloques específicos de la plataforma del cuerpo del mensaje.

Ejemplo: Mensaje de notificación con una acción de clic asociada

En el siguiente ejemplo de solicitud de envío, se envía un título de notificación común a todas las plataformas, así como una acción para que realice la app, como respuesta a la interacción del usuario con la notificación. Esta es una aproximación del efecto visual en el dispositivo de un usuario:

Dibujo simple de un usuario que presiona la pantalla para abrir una página web

Node.js

const topicName = 'industry-tech';

const message = {
  notification: {
    title: 'Breaking News....'
  },
  android: {
    notification: {
      clickAction: 'news_intent'
    }
  },
  apns: {
    payload: {
      aps: {
        'category': 'INVITE_CATEGORY'
      }
    }
  },
  webpush: {
    fcmOptions: {
      link: 'breakingnews.html'
    }
  },
  topic: topicName,
};

getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
     "topic":"industry-tech",
     "notification":{
       "title":"Breaking News...",
     },
     "android":{
       "notification":{
         "click_action":"news_intent"
       }
     },
     "apns":{
       "payload":{
         "aps":{
           "category" : "INVITE_CATEGORY"
         }
       },
     },
     "webpush":{
       "fcm_options":{
         "link":"breakingnews.html"
       }
     }
   }
 }

Consulta la documentación de referencia de HTTP v1 para obtener información detallada sobre las claves disponibles en los bloques específicos de la plataforma del cuerpo del mensaje.

Ejemplo: Mensaje de notificación con opciones de localización

En el siguiente ejemplo de solicitud de envío, se envían opciones de localización para que el cliente muestre mensajes localizados. Esta es una aproximación del efecto visual en el dispositivo de un usuario:

Dibujo simple de dos dispositivos que muestran texto en inglés y español

Node.js

var topicName = 'industry-tech';

var message = {
  android: {
    ttl: 3600000,
    notification: {
      bodyLocKey: 'STOCK_NOTIFICATION_BODY',
      bodyLocArgs: ['FooCorp', '11.80', '835.67', '1.43']
    }
  },
  apns: {
    payload: {
      aps: {
        alert: {
          locKey: 'STOCK_NOTIFICATION_BODY',
          locArgs: ['FooCorp', '11.80', '835.67', '1.43']
        }
      }
    }
  },
  topic: topicName,
};

getMessaging().send(message)
  .then((response) => {
    // Response is a message ID string.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

REST

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
             "topic":"Tech",
             "android":{
               "ttl":"3600s",
               "notification":{
                 "body_loc_key": "STOCK_NOTIFICATION_BODY",
                 "body_loc_args":  ["FooCorp", "11.80", "835.67", "1.43"],
               },
             },
             "apns":{
               "payload":{
                 "aps":{
                   "alert" : {
                     "loc-key": "STOCK_NOTIFICATION_BODY",
                     "loc-args":  ["FooCorp", "11.80", "835.67", "1.43"],
                    },
                 },
               },
             },
  },
}'

Consulta la documentación de referencia de HTTP v1 para obtener información detallada sobre las claves disponibles en los bloques específicos de la plataforma del cuerpo del mensaje.

Códigos de error de REST para la API de HTTP v1

Las respuestas de errores de HTTP para la API de HTTP v1 contienen un código de error, un mensaje de error y un estado de error. También pueden contener un array details con más detalles sobre el error.

A continuación, se muestran dos ejemplos de respuestas de error:

Ejemplo 1: Respuesta de error de una solicitud a la API de HTTP v1 con un valor no válido en un mensaje de datos

{
  "error": {
    "code": 400,
    "message": "Invalid value at 'message.data[0].value' (TYPE_STRING), 12",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "message.data[0].value",
            "description": "Invalid value at 'message.data[0].value' (TYPE_STRING), 12"
          }
        ]
      }
    ]
  }
}

Ejemplo 2: Respuesta de error de una solicitud a la API de HTTP v1 con un token de registro no válido

{
  "error": {
    "code": 400,
    "message": "The registration token is not a valid FCM registration token",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
        "errorCode": "INVALID_ARGUMENT"
      }
    ]
   }
}

Ten en cuenta que ambos mensajes tienen el mismo código y el mismo estado, pero el array de detalles contiene valores de tipos diferentes. El primer ejemplo tiene el tipo type.googleapis.com/google.rpc.BadRequest, que indica un error en los valores de la solicitud. El segundo ejemplo con el tipo type.googleapis.com/google.firebase.fcm.v1.FcmError tiene un error específico de FCM. En muchos errores, la matriz de detalles contiene la información que necesitarás para depurar y encontrar una solución.

En la siguiente tabla, se enumeran los códigos de error de la API de REST v1 de FCM y sus descripciones.

Código de error Descripción y pasos de resolución
UNSPECIFIED_ERROR No hay más información disponible sobre este error. Ninguno
INVALID_ARGUMENT (código de error de HTTP = 400) Los parámetros de la solicitud no eran válidos. Se muestra una extensión de tipo google.rpc.BadRequest para especificar qué campo no era válido. Entre las posibles causas, se incluyen un registro no válido, un nombre de paquete no válido, un mensaje demasiado grande, una clave de datos no válida, un TTL no válido y otros parámetros no válidos.
Registro no válido: Verifica el formato del token de registro que pasaste al servidor. Asegúrate de que coincida con el token de registro que la app cliente recibe cuando se registra en FCM. No lo trunques el token ni agregues caracteres adicionales.
Nombre de paquete no válido: Asegúrate de que el mensaje se haya dirigido a un token de registro cuyo nombre de paquete coincida con el valor pasado en la solicitud.
Mensaje demasiado grande: Verifica que el tamaño total de los datos de carga útil incluidos en un mensaje no supere los límites de FCM: 4,096 bytes para la mayoría de los mensajes, o 2,048 bytes para los mensajes a temas. Esto incluye las claves y los valores.
Clave de datos no válida: Verifica que los datos de carga útil no contengan una clave (como from, gcm o cualquier valor con el prefijo de Google) que FCM usa de forma interna. Ten en cuenta que FCM también usa algunas palabras (como collapse_key), pero se permiten en la carga útil. En este caso, el valor de FCM anulará el valor de la carga útil.
TTL no válido: Verifica que el valor que se usa en ttl sea un número entero que represente la duración en segundos entre 0 y 2,419,200 (4 semanas).
Parámetros no válidos: Verifica que los parámetros proporcionados tengan el nombre y el tipo correctos.
UNREGISTERED (código de error de HTTP = 404) Se canceló el registro de la instancia de la app en FCM. Por lo general, esto significa que el token utilizado ya no es válido y se debe usar uno nuevo. Este error puede deberse a tokens de registro faltantes o no registrados.
Falta el registro: Si el objetivo del mensaje es un valor token, verifica que la solicitud contenga un token de registro.
No registrado: Un token de registro existente puede dejar de ser válido en diversas situaciones, como las siguientes:
- Si la app cliente deja de estar registrada en FCM.
- Si se cancela el registro de la app cliente de forma automática, lo cual puede ocurrir si el usuario desinstala la aplicación. Por ejemplo, en iOS esto sucede si el servicio de comentarios de APNs informó que los tokens de APNs no son válidos.
- Si caduca el token de registro (por ejemplo, porque Google decidió actualizar estos tokens o porque caducó el token de APNs para los dispositivos iOS).
- Si la app cliente se actualiza, pero la nueva versión no está configurada para recibir mensajes.
En todos estos casos, debes quitar este token de registro del servidor de apps y dejar de utilizarlo para enviar mensajes.
SENDER_ID_MISMATCH (código de error de HTTP = 403) El ID de remitente autenticado es diferente del ID de remitente del token de registro. Un token de registro está asociado con un determinado grupo de emisores. Cuando una app cliente se registra para FCM, debe especificar qué remitentes tienen autorización para enviar mensajes. Debes utilizar el ID de uno de esos remitentes cuando envíes mensajes a la app cliente. Si cambias a otro diferente, los tokens de registro existentes no funcionarán.
QUOTA_EXCEEDED (código de error de HTTP = 429): Se superó el límite de envío para el destino del mensaje. Se muestra una extensión de tipo google.rpc.QuotaFailure para especificar qué cuota se superó. Este error puede deberse a que se excedió la cuota de frecuencia de mensajes, la cuota de frecuencia de mensajes de dispositivos o la cuota de frecuencia de mensajes de temas.
Tasa de mensajes excedida: La frecuencia de envío de mensajes es demasiado alta. Debes reducir la tasa general a la que envías mensajes. Usa la retirada exponencial con un retraso inicial mínimo de 1 minuto para reintentar los mensajes rechazados.
Tasa de mensajes de dispositivos excedida: La tasa de mensajes a un dispositivo determinado es demasiado alta. Consulta el límite de frecuencia de mensajes a un solo dispositivo. Reduce la cantidad de mensajes enviados a este dispositivo y usa la retirada exponencial para volver a intentar el envío.
Tasa de mensajes de temas excedida: La tasa de mensajes a suscriptores de un tema particular es demasiado alta. Reduce la cantidad de mensajes enviados a este tema y usa la retirada exponencial con una demora inicial mínima de 1 minuto para volver a intentar el envío.
UNAVAILABLE (código de error de HTTP = 503). El servidor está sobrecargado. El servidor no pudo procesar la solicitud a tiempo. Vuelve a intentar con la misma solicitud, pero haz lo siguiente:
- Respeta el encabezado Reintento posterior si se incluye en la respuesta del servidor de conexiones de FCM.
- Implementa la retirada exponencial en el mecanismo de reintento. (p. ej., si esperaste un segundo antes del primer intento, espera al menos dos segundos antes del próximo, luego, 4 segundos y así sucesivamente). Si envías varios mensajes, considera aplicar Jitter. Para obtener más información, consulta Administra los reintentos. Los remitentes que causen problemas corren el riesgo de ser incluidos en una lista de bloqueo.
INTERNAL (código de error de HTTP = 500) Se produjo un error interno desconocido. Se produjo un error en el servidor mientras se intentaba procesar la solicitud. Puedes volver a intentar con la misma solicitud; para ello, sigue las sugerencias incluidas en Administra los reintentos. Si el error persiste, comunícate con el equipo de asistencia de Firebase.
THIRD_PARTY_AUTH_ERROR (código de error de HTTP = 401): El certificado de APNs o la clave de autorización de notificaciones push web no eran válidos o faltaban. No se pudo enviar un mensaje destinado a un dispositivo iOS o a un registro push web. Verifica la validez de tus credenciales de desarrollo y producción.

Códigos de error del administrador

En la siguiente tabla, se muestra una lista de los códigos de error de la API de Admin de FCM de Firebase y sus descripciones, además de los pasos recomendados para resolverlos.

Código de error Descripción y pasos de resolución
messaging/invalid-argument Se proporcionó un argumento no válido al método de FCM. El mensaje de error debe incluir información adicional.
messaging/invalid-recipient El destinatario del mensaje no es válido. El mensaje de error debe incluir información adicional.
messaging/invalid-payload Se proporcionó un objeto de carga útil del mensaje no válido. El mensaje de error debe incluir información adicional.
messaging/invalid-data-payload-key La carga útil del mensaje de datos contiene una clave no válida. Consulta la documentación de referencia de DataMessagePayload para ver las claves restringidas.
messaging/payload-size-limit-exceeded La carga útil del mensaje que se proporcionó supera el límite de tamaño de FCM. El límite es de 4,096 bytes para la mayoría de los mensajes. Para los mensajes enviados a los temas, el límite es de 2,048 bytes. El tamaño total de la carga útil incluye las claves y los valores.
messaging/invalid-options Se proporcionó un objeto de opciones de mensaje no válido. El mensaje de error debe incluir información adicional.
messaging/invalid-registration-token Se proporcionó un token de registro no válido. Asegúrate de que coincida con el token de registro que la app cliente recibe cuando se registra en FCM. No lo trunques ni le agregues caracteres adicionales.
messaging/registration-token-not-registered El token de registro que se proporcionó no está registrado. Se puede cancelar el registro de un token válido por distintos motivos, como los siguientes:
  • La app cliente canceló su registro de FCM.
  • Se canceló automáticamente el registro de la app cliente. Esto puede ocurrir si el usuario desinstala la aplicación o, en Apple, si el servicio de comentarios de APNS informó que el token de APNS no es válido.
  • El token de registro venció. Por ejemplo, porque Google decidió actualizar los tokens de registro o porque venció el token de APNS para los dispositivos de Apple.
  • Se actualizó la app cliente, pero la versión nueva no está configurada para recibir mensajes.
En todos estos casos, quita el token de registro y deja de usarlo para enviar mensajes.
messaging/invalid-package-name El mensaje se dirigió a un token de registro cuyo nombre de paquete no coincide con la opción restrictedPackageName proporcionada.
messaging/message-rate-exceeded La tasa de mensajes a un objetivo específico es demasiado alta. Reduce la cantidad de mensajes que se envían a este dispositivo o tema, y no intentes reenviar mensajes de inmediato al mismo destino.
messaging/device-message-rate-exceeded La tasa de mensajes a un dispositivo específico es demasiado alta. Reduce la cantidad de mensajes que se envían a este dispositivo y no intentes volver a enviarle mensajes a este dispositivo de inmediato.
messaging/topics-message-rate-exceeded La tasa de mensajes a suscriptores de un tema particular es demasiado alta. Reduce la cantidad de mensajes enviados a este tema y no intentes volver a enviar mensajes de inmediato.
messaging/too-many-topics Un token de registro se suscribió a la cantidad máxima de temas y no se puede suscribir a ningún otro.
messaging/invalid-apns-credentials No se pudo enviar un mensaje destinado a un dispositivo Apple, ya que el certificado SSL de APNS obligatorio venció o no se subió. Verifica la validez de los certificados de desarrollo y producción.
messaging/mismatched-credential La credencial que se usó para autenticar este SDK no tiene permiso para enviar mensajes al dispositivo que corresponde al token de registro proporcionado. Asegúrate de que el token de registro y la credencial pertenecen al mismo proyecto de Firebase. Consulta Agrega Firebase a tu app para ver la documentación sobre cómo autenticar los Firebase Admin SDK.
messaging/authentication-error El SDK no pudo autenticarse en los servidores de FCM. Asegúrate de autenticar Firebase Admin SDK con una credencial que tenga los permisos adecuados para enviar mensajes de FCM. Consulta Agrega Firebase a tu app para ver la documentación sobre cómo autenticar los Firebase Admin SDK.
messaging/server-unavailable El servidor de FCM no pudo procesar la solicitud a tiempo. Vuelve a intentarlo con la misma solicitud, pero esta vez haz lo siguiente:
  • Si se incluye el encabezado Retry-After en la respuesta del servidor de conexiones de FCM, debes respetar el tiempo de espera que se especifica.
  • Implementa la retirada exponencial en el mecanismo de reintento. Por ejemplo, si esperaste un segundo antes del primer intento, espera al menos dos segundos antes del próximo; luego, cuatro segundos y así sucesivamente. Si envías varios mensajes, agrega una demora independiente a cada uno con un valor aleatorio adicional, a fin de evitar emitir una nueva solicitud para todos los mensajes de forma simultánea.
Los remitentes que causen problemas corren el riesgo de ser incluidos en una lista de entidades bloqueadas.
messaging/internal-error Se produjo un error en el servidor de FCM mientras se intentaba procesar la solicitud. Puedes volver a intentar con la misma solicitud; para ello, sigue los requisitos que se enumeran en la fila messaging/server-unavailable anterior. Si el error persiste, informa el problema a nuestro canal de asistencia de informe de errores.
messaging/unknown-error Se obtuvo como resultado un error desconocido del servidor. Consulta la respuesta del servidor sin procesar en el mensaje de error para ver más detalles. Si recibes este error, informa el mensaje de error completo a nuestro canal de asistencia de informes de errores.

Envía mensajes con los protocolos del servidor de apps heredados

Si actualmente usas los protocolos heredados, crea solicitudes de mensaje como se muestra en esta sección. Ten en cuenta que, si envías mensajes a varias plataformas a través de HTTP, el protocolo v1 puede simplificar tus solicitudes de mensaje de forma considerable.

Envía mensajes a dispositivos específicos

A fin de enviar mensajes a dispositivos específicos, asigna a la clave to el token de registro para la instancia de app específica. Consulta la información de configuración del cliente para tu plataforma si deseas obtener más información sobre los tokens de registro.

Solicitud HTTP POST

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

Respuesta HTTP

{ "multicast_id": 108,
  "success": 1,
  "failure": 0,
  "results": [
    { "message_id": "1:08" }
  ]
}

Mensaje XMPP

<message id="">
  <gcm xmlns="google:mobile:data">
    { "data": {
      "score": "5x1",
      "time": "15:10"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }
  </gcm>
</message>

Respuesta XMPP

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

El servidor de conexiones XMPP proporciona algunas otras opciones de respuesta. Consulta Formato de respuesta del servidor.

Para ver la lista completa de opciones de mensajes disponibles cuando envías mensajes descendentes a las apps cliente, consulta la información de referencia del protocolo del servidor de conexiones que seleccionaste: HTTP o XMPP.

Envía mensajes a temas

Enviar mensajes a un tema Firebase Cloud Messaging es muy similar a enviar mensajes a un dispositivo individual o a un grupo de usuarios. El servidor de apps establece la clave to con el valor /topics/yourTopic. Los desarrolladores pueden elegir cualquier nombre de tema que coincida con la expresión regular: "/topics/[a-zA-Z0-9-_.~%]+".

Para enviar mensajes a combinaciones de varios temas, el servidor de apps debe configurar la clave condition (en lugar de la clave to) como una condición booleana que especifique los temas de destino. Por ejemplo, para enviar mensajes a dispositivos suscritos a TopicA y a TopicB o TopicC:

'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)

En primer lugar, FCM evalúa las condiciones en paréntesis y, luego, evalúa la expresión de izquierda a derecha. En la expresión que se observa en este ejemplo, los usuarios suscritos a uno solo de los temas no recibirán el mensaje. Asimismo, los usuarios que no estén suscritos a TopicA tampoco lo recibirán. Las siguientes combinaciones sí lo reciben:

  • TopicA y TopicB
  • TopicA y TopicC

Puedes incluir hasta cinco temas en tu expresión condicional, y se admiten paréntesis. Operadores admitidos: && y ||.

Solicitud HTTP POST del tema

Envía mensajes a un solo tema:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Envía mensajes a dispositivos suscritos a los temas "dogs" o "cats":

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Respuesta HTTP del tema

// Success example:
{
  "message_id": "1023456"
}

// failure example:
{
  "error": "TopicsMessageRateExceeded"
}

Mensaje XMPP del tema

Envía mensajes a un solo tema:

<message id="">
  <gcm xmlns="google:mobile:data">


  </gcm>
</message>

Envía mensajes a dispositivos suscritos a los temas "dogs" o "cats":

<message id="">
  <gcm xmlns="google:mobile:data">


  </gcm>
</message>

Respuesta XMPP del tema

// Success example:
{
  "message_id": "1023456"
}

// failure example:
{
  "error": "TopicsMessageRateExceeded"
}

Cuando realizas una solicitud de envío por temas, pueden pasar hasta 30 segundos antes de que el servidor de FCM muestre una respuesta de ejecución correcta o con errores. Asegúrate de configurar el valor de tiempo de espera del servidor de apps en la solicitud de manera acorde.

Envía mensajes a grupos de dispositivos

Enviar mensajes a un grupo de dispositivos con las APIs heredadas obsoletas 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. Los ejemplos en esta sección muestran cómo enviar mensajes de datos a grupos de dispositivos en protocolos heredados 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: la 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: la 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 (registration_ids) 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: la 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: la 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 ninguno de 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.

Métodos de envío heredados del Firebase Admin SDK

El SDK de Firebase Admin para Node.js admite métodos de envío (FCM) de mensajes basados en la API del servidor de FCM heredada. Estos métodos aceptan argumentos diferentes en comparación con el método send(). Usa el método send() siempre que puedas y los métodos descritos en esta página solo cuando envíes mensajes a dispositivos individuales o grupos de dispositivos.

Envía mensajes a dispositivos individuales

Puedes pasar un token de registro al método sendToDevice() para enviar un mensaje a ese dispositivo:

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the device corresponding to the provided
// registration token.
getMessaging().sendToDevice(registrationToken, payload)
  .then((response) => {
    // See the MessagingDevicesResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

El método sendToDevice() también puede enviar un mensaje de multidifusión (es decir, un mensaje a varios dispositivos). Para ello, pasa un array de tokens de registro, en lugar de uno solo:

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...',
  // ...
  'ecupwIfBy1w:APA91bFtuMY7MktgxA3Au_Qx7cKqnf...'
];

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the devices corresponding to the provided
// registration tokens.
getMessaging().sendToDevice(registrationTokens, payload)
  .then((response) => {
    // See the MessagingDevicesResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

El método sendToDevice() muestra una promesa que se resuelve con un objeto MessagingDevicesResponse que contiene la respuesta de FCM. El tipo de datos que se muestra tiene el mismo formato cuando se pasa un solo token de registro o un array de tokens de registro.

Algunos casos, como un error de autenticación o un límite de frecuencia, hacen que falle el procesamiento del mensaje completo. En estos casos, la promesa resultante de sendToDevice() se rechaza con un error. Para ver una lista completa de los códigos de error con descripciones y pasos para su resolución, consulta Errores de la API de Admin de FCM.

Envía mensajes a un grupo de dispositivos

El método sendToDeviceGroup() te permite enviar un mensaje a un grupo de dispositivos. Para ello, debes especificar la clave de notificación para ese grupo de dispositivos:

Node.js

// See the "Managing device groups" link above on how to generate a
// notification key.
const notificationKey = 'some-notification-key';

// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

// Send a message to the device group corresponding to the provided
// notification key.
getMessaging().sendToDeviceGroup(notificationKey, payload)
  .then((response) => {
    // See the MessagingDeviceGroupResponse reference documentation for
    // the contents of response.
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

El método sendToDeviceGroup() muestra una promesa que se resuelve con un objeto MessagingDevicesResponse que contiene la respuesta de FCM.

Algunos casos, como un error de autenticación o un límite de frecuencia, hacen que falle el procesamiento del mensaje completo. En estos casos, la promesa resultante de sendToDeviceGroup() se rechaza con un error. Para ver una lista completa de los códigos de error con descripciones y pasos para su resolución, consulta Errores de la API de Admin de FCM.

Define la carga útil del mensaje

Los métodos anteriores, basados en los protocolos heredados de FCM, aceptan una carga útil de mensajes como su segundo argumento y admiten tanto los mensajes de notificación como los de datos. Para especificar uno o ambos tipos de mensaje, puedes crear un objeto con las claves data o notification. Por ejemplo, a continuación, se muestra cómo definir distintos tipos de cargas útiles de mensaje:

Mensaje de notificación

const payload = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  }
};

Mensaje de datos

const payload = {
  data: {
    score: '850',
    time: '2:45'
  }
};

Mensaje combinado

const payload = {
  notification: {
    title: '$FooCorp up 1.43% on the day',
    body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
  },
  data: {
    stock: 'GOOG',
    open: '829.62',
    close: '635.67'
  }
};

Las cargas útiles de mensajes de notificación tienen un subconjunto predefinido de propiedades válidas y difieren levemente, según el sistema operativo móvil al que te orientas. Consulta la documentación de referencia de NotificationMessagePayload para ver una lista completa.

Las cargas útiles de mensajes de datos se componen de pares clave-valor personalizados con algunas restricciones, incluido el hecho de que los valores deben ser strings. Consulta la documentación de referencia de DataMessagePayload para ver una lista completa de las restricciones.

Define las opciones del mensaje

Los métodos anteriores, basados en los protocolos heredados de FCM, aceptan un tercer argumento opcional en el que se especifican algunas opciones para el mensaje. En el siguiente ejemplo, se envía un mensaje con prioridad alta a un dispositivo, que vence después de 24 horas:

Node.js

// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';

// See the "Defining the message payload" section above for details
// on how to define a message payload.
const payload = {
  notification: {
    title: 'Urgent action needed!',
    body: 'Urgent action is needed to prevent your account from being disabled!'
  }
};

// Set the message as high priority and have it expire after 24 hours.
const options = {
  priority: 'high',
  timeToLive: 60 * 60 * 24
};

// Send a message to the device corresponding to the provided
// registration token with the provided options.
getMessaging().sendToDevice(registrationToken, payload, options)
  .then((response) => {
    console.log('Successfully sent message:', response);
  })
  .catch((error) => {
    console.log('Error sending message:', error);
  });

Consulta la documentación de referencia de MessagingOptions para ver una lista completa de las opciones disponibles.