Создание запросов на отправку сервера приложений

Используя Firebase Admin SDK или протоколы сервера приложений FCM , вы можете создавать запросы сообщений и отправлять их на следующие типы целей:

  • Название темы
  • Состояние
  • Токен регистрации устройства
  • Имя группы устройств (только протокол)

Вы можете отправлять сообщения с полезными данными уведомления, состоящими из предопределенных полей, полезными данными с вашими собственными пользовательскими полями или сообщением, содержащим оба типа полезных данных. Дополнительные сведения см. в разделе Типы сообщений .

В примерах на этой странице показано, как отправлять уведомления с помощью Firebase Admin SDK (который поддерживает Node , Java , Python , C# и Go ) и протокола HTTP v1 .

Отправка сообщений на определенные устройства

Чтобы отправить на одно конкретное устройство, передайте токен регистрации устройства, как показано. См. информацию о настройке клиента для вашей платформы, чтобы узнать больше о регистрационных токенах.

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

В случае успеха каждый метод отправки возвращает идентификатор сообщения. Firebase Admin SDK возвращает строку идентификатора в формате projects/{project_id}/messages/{message_id} . Ответ протокола HTTP представляет собой один ключ JSON:

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

Отправка сообщений на несколько устройств

API-интерфейсы Admin FCM позволяют осуществлять многоадресную рассылку сообщений в список токенов регистрации устройств. Вы можете указать до 500 токенов регистрации устройств для каждого вызова.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Возвращаемое значение представляет собой список токенов, соответствующий порядку входных токенов. Это полезно, если вы хотите проверить, какие токены привели к ошибкам.

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

Ява

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

Питон

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

Идти

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

С#

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

Отправлять сообщения в темы

После того как вы создали тему, подписав на нее экземпляры клиентского приложения на стороне клиента или через серверный API , вы можете отправлять сообщения в тему. Если вы впервые создаете запросы на отправку для FCM , ознакомьтесь с руководством по вашей серверной среде и FCM для получения важной вводной информации и информации о настройке.

В логике отправки на серверной стороне укажите желаемое имя темы, как показано:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

Чтобы отправить сообщение по нескольким темам, укажите условие , которое представляет собой логическое выражение, определяющее целевые темы. Например, следующее условие отправит сообщения на устройства, подписанные на TopicA и TopicB или TopicC :

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

FCM сначала оценивает все условия в скобках, а затем оценивает выражение слева направо. В приведенном выше выражении пользователь, подписанный на какую-либо отдельную тему, не получает сообщение. Аналогично, пользователь, не подписанный на TopicA , не получит сообщение. Эти комбинации получают его:

  • TopicA и TopicB
  • TopicA и TopicC

В условное выражение можно включить до пяти тем.

Чтобы отправить условие:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

Отправка сообщений группам устройств

Чтобы отправлять сообщения группам устройств, используйте API HTTP v1. Если в настоящее время вы отправляете сообщения группам устройств, используя устаревшие API отправки для HTTP или XMPP или любую из более старых версий Firebase Admin SDK для Node.js на основе устаревших протоколов, мы настоятельно рекомендуем вам перейти на API HTTP v1 при первой же возможности. Устаревшие API отправки будут отключены и удалены в июне 2024 года.

Отправка сообщений группе устройств очень похожа на отправку сообщений отдельному устройству: для авторизации запросов на отправку используется тот же метод. Установите в поле token ключ группового уведомления:

ОТДЫХ

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

команда 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

Отправьте пакет сообщений

Admin SDK поддерживают пакетную отправку сообщений. Вы можете сгруппировать до 500 сообщений в один пакет и отправить их все за один вызов API, что значительно улучшит производительность по сравнению с отправкой отдельных HTTP-запросов для каждого сообщения.

Эту функцию можно использовать для создания индивидуального набора сообщений и отправки их разным получателям, включая темы или определенные токены регистрации устройства. Используйте эту функцию, например, когда вам нужно одновременно отправлять сообщения разным аудиториям с немного разными деталями в теле сообщения.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Отправка прямых сообщений с включенной загрузкой (только для Android)

Вы можете отправлять сообщения на устройства в режиме прямой загрузки, используя HTTP v1 или устаревшие API-интерфейсы HTTP. Перед отправкой на устройства в режиме прямой загрузки убедитесь, что вы выполнили действия, позволяющие клиентским устройствам получать сообщения FCM в режиме прямой загрузки .

Отправка с использованием HTTP API FCM v1.

Запрос сообщения должен включать ключ "direct_boot_ok" : true в параметрах AndroidConfig тела запроса. Например:

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

Настраивайте сообщения на разных платформах

Firebase Admin SDK и HTTP-протокол FCM v1 позволяют вашим запросам сообщений устанавливать все поля, доступные в объекте message . Это включает в себя:

  • общий набор полей, которые будут интерпретироваться всеми экземплярами приложения, получающими сообщение.
  • наборы полей, зависящие от платформы, такие как AndroidConfig и WebpushConfig , интерпретируемые только экземплярами приложения, работающими на указанной платформе.

Блоки, специфичные для конкретной платформы, дают вам возможность настраивать сообщения для разных платформ, чтобы гарантировать их правильную обработку при получении. Серверная часть FCM учтет все указанные параметры и настроит сообщение для каждой платформы.

Когда использовать общие поля

Используйте общие поля, если вы:

  • Таргетинг на экземпляры приложений на всех платформах — Apple, Android и в Интернете.
  • Отправка сообщений в темы

Все экземпляры приложения, независимо от платформы, могут интерпретировать следующие общие поля:

Когда использовать поля, специфичные для платформы

Используйте поля, специфичные для платформы, если вы хотите:

  • Отправлять поля только на определенные платформы
  • Отправляйте поля, специфичные для платформы , в дополнение к общим полям.

Если вы хотите отправлять значения только на определенные платформы, не используйте общие поля; используйте поля, специфичные для платформы. Например, чтобы отправить уведомление только на платформы Apple и в Интернет, но не на Android, необходимо использовать два отдельных набора полей: один для Apple и один для Интернета.

Когда вы отправляете сообщения с определенными параметрами доставки , используйте поля для конкретной платформы, чтобы установить их. Если хотите, вы можете указать разные значения для каждой платформы. Однако даже если вы хотите установить по существу одно и то же значение для разных платформ, вы должны использовать поля, специфичные для платформы. Это связано с тем, что каждая платформа может интерпретировать значение немного по-разному — например, срок жизни на Android устанавливается как срок действия в секундах, а на Apple — как дата истечения срока действия.

Пример: уведомление с параметрами цвета и значка.

В этом примере запроса на отправку отправляется общий заголовок и содержимое уведомления на все платформы, но он также отправляет некоторые переопределения для конкретной платформы на устройства Android.

Для Android запрос устанавливает специальный значок и цвет для отображения на устройствах Android. Как отмечено в ссылке на AndroidNotification , цвет указывается в формате #rrggbb, а изображение должно представлять собой ресурс значка с возможностью рисования, локальный для приложения Android.

Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок двух устройств, одно из которых имеет собственный значок и цвет.

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

Ява

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

Питон

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',
)

Идти

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

С#

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с пользовательским изображением.

В следующем примере запроса на отправку на все платформы отправляется общий заголовок уведомления, а также изображение. Вот приблизительный визуальный эффект на устройстве пользователя:

Простое рисование изображения в уведомлении о показе

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с соответствующим действием по клику

В следующем примере запроса на отправку на все платформы отправляется общий заголовок уведомления, а также действие, которое приложение должно выполнить в ответ на взаимодействие пользователя с уведомлением. Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок касания пользователя, открывающего веб-страницу

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с опциями локализации

В следующем примере запроса на отправку клиенту отправляются параметры локализации для отображения локализованных сообщений. Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок двух устройств, отображающих текст на английском и испанском языках.

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

ОТДЫХ

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"],
                    },
                 },
               },
             },
  },
}'

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Коды ошибок REST для API HTTP v1

Ответы об ошибках HTTP для API HTTP v1 содержат код ошибки, сообщение об ошибке и статус ошибки. Они также могут содержать массив details с более подробной информацией об ошибке.

Вот два примера ответов об ошибках:

Пример 1. Ответ об ошибке на запрос API HTTP v1 с недопустимым значением в сообщении данных.

{
  "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"
          }
        ]
      }
    ]
  }
}

Пример 2. Ответ об ошибке на запрос API HTTP v1 с недействительным токеном регистрации.

{
  "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"
      }
    ]
   }
}

Обратите внимание, что оба сообщения имеют одинаковый код и статус, но массив сведений содержит значения разных типов. Первый пример имеет тип type.googleapis.com/google.rpc.BadRequest что указывает на ошибку в значениях запроса. Во втором примере с типом type.googleapis.com/google.firebase.fcm.v1.FcmError имеется ошибка, специфичная для FCM. Для многих ошибок массив сведений содержит информацию, необходимую для отладки и поиска решения.

В следующей таблице перечислены коды ошибок REST API FCM v1 и их описания.

Код ошибки Описание и шаги решения
UNSPECIFIED_ERROR Дополнительной информации об этой ошибке нет. Никто.
INVALID_ARGUMENT (код ошибки HTTP = 400) Параметры запроса недействительны. Расширение типа google.rpc.BadRequest возвращается, чтобы указать, какое поле было недействительным. Возможные причины: неверная регистрация, недопустимое имя пакета, слишком большое сообщение, неверный ключ данных, неверный срок жизни или другие недопустимые параметры.
Неверная регистрация : проверьте формат регистрационного токена, который вы передаете на сервер. Убедитесь, что он соответствует регистрационному токену, который клиентское приложение получает при регистрации в FCM. Не обрезайте токен и не добавляйте дополнительные символы.
Недопустимое имя пакета . Убедитесь, что сообщение было адресовано регистрационному токену, имя пакета которого соответствует значению, переданному в запросе.
Сообщение слишком большое : убедитесь, что общий размер полезных данных, включенных в сообщение, не превышает ограничения FCM: 4096 байт для большинства сообщений или 2048 байт в случае сообщений в темах. Сюда входят как ключи, так и значения.
Неверный ключ данных . Убедитесь, что полезные данные не содержат ключ (например, from, gcm или любое значение с префиксом Google), который используется внутри FCM. Обратите внимание, что некоторые слова (например, свернуть_ключ) также используются FCM, но разрешены в полезных данных, и в этом случае значение полезных данных будет переопределено значением FCM.
Неверный срок жизни : убедитесь, что значение, используемое в сроке жизни, является целым числом, представляющим продолжительность в секундах от 0 до 2 419 200 (4 недели).
Недопустимые параметры . Убедитесь, что предоставленные параметры имеют правильное имя и тип.
UNREGISTERED (код ошибки HTTP = 404). Экземпляр приложения не зарегистрирован в FCM. Обычно это означает, что используемый токен больше не действителен и необходимо использовать новый. Эта ошибка может быть вызвана отсутствием токенов регистрации или незарегистрированными токенами.
Отсутствует регистрация . Если целью сообщения является значение token , убедитесь, что запрос содержит токен регистрации.
Не зарегистрировано : существующий регистрационный токен может перестать быть действительным в ряде сценариев, в том числе:
- Если клиентское приложение отменяет регистрацию в FCM.
- Если регистрация клиентского приложения автоматически отменяется, что может произойти, если пользователь удалит приложение. Например, в iOS, если служба обратной связи APNs сообщила, что токен APNs недействителен.
- Если срок действия токена регистрации истек (например, Google может принять решение обновить токены регистрации или срок действия токена APNs истек для устройств iOS).
- Если клиентское приложение обновлено, но новая версия не настроена на получение сообщений.
Во всех этих случаях удалите этот регистрационный токен с сервера приложений и прекратите использовать его для отправки сообщений.
SENDER_ID_MISMATCH (код ошибки HTTP = 403) Идентификатор проверенного отправителя отличается от идентификатора отправителя для токена регистрации. Регистрационный токен привязан к определенной группе отправителей. Когда клиентское приложение регистрируется в FCM, оно должно указать, каким отправителям разрешено отправлять сообщения. Вам следует использовать один из этих идентификаторов отправителя при отправке сообщений в клиентское приложение. Если вы переключитесь на другого отправителя, существующие регистрационные токены не будут работать.
QUOTA_EXCEEDED (код ошибки HTTP = 429) Превышен лимит отправки для целевого сообщения. Расширение типа google.rpc.QuotaFailure возвращается, чтобы указать, какая квота была превышена. Эта ошибка может быть вызвана превышением квоты скорости сообщения, превышением квоты скорости сообщения устройства или превышением квоты скорости сообщения темы.
Превышена скорость передачи сообщений : Скорость отправки сообщений слишком высока. Вы должны снизить общую скорость отправки сообщений. Используйте экспоненциальную отсрочку с минимальной начальной задержкой в ​​1 минуту для повторной попытки отклоненных сообщений.
Превышена частота сообщений устройства : Скорость сообщений на конкретное устройство слишком высока. См. ограничение скорости передачи сообщений для одного устройства . Уменьшите количество сообщений, отправляемых на это устройство, и используйте экспоненциальную отсрочку для повторной отправки.
Превышена частота сообщений по теме : Частота сообщений подписчикам по определенной теме слишком высока. Уменьшите количество сообщений, отправляемых по этой теме, и используйте экспоненциальную задержку с минимальной начальной задержкой в ​​1 минуту для повторной отправки.
UNAVAILABLE (код ошибки HTTP = 503) Сервер перегружен. Сервер не смог вовремя обработать запрос. Повторите тот же запрос, но вам необходимо:
— Учитывайте заголовок Retry-After, если он включен в ответ сервера соединений FCM.
- Внедрите экспоненциальную отсрочку в механизме повторных попыток. (например, если вы подождали одну секунду перед первой повторной попыткой, подождите не менее двух секунд перед следующей, затем 4 секунды и так далее). Если вы отправляете несколько сообщений, рассмотрите возможность применения дрожания. Дополнительные сведения см. в разделе «Обработка повторных попыток» или проверьте панель состояния FCM , чтобы определить, есть ли какие-либо текущие сбои в обслуживании, влияющие на FCM. Отправители, вызывающие проблемы, рискуют попасть в список запрещенных.
INTERNAL (код ошибки HTTP = 500) Произошла неизвестная внутренняя ошибка. Сервер обнаружил ошибку при попытке обработать запрос. Вы можете повторить тот же запрос, следуя рекомендациям в разделе «Обработка повторных попыток» или проверке панели состояния FCM . чтобы определить, есть ли какие-либо постоянные сбои в обслуживании, влияющие на FCM. Если ошибка не исчезнет, ​​обратитесь в службу поддержки Firebase.
THIRD_PARTY_AUTH_ERROR (код ошибки HTTP = 401) Сертификат APN или ключ аутентификации через веб-приложение недействительны или отсутствуют. Не удалось отправить сообщение, предназначенное для устройства iOS, или веб-приложение. Проверьте действительность своих учетных данных для разработки и производства.

Коды ошибок администратора

В следующей таблице перечислены коды ошибок Firebase Admin FCM API и их описания, включая рекомендуемые шаги по устранению.

Код ошибки Описание и шаги решения
messaging/invalid-argument Методу FCM предоставлен недопустимый аргумент. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-recipient Предполагаемый получатель сообщения недействителен. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-payload Предоставлен недопустимый объект полезных данных сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-data-payload-key Полезная нагрузка сообщения данных содержит недопустимый ключ. См. справочную документацию по DataMessagePayload для получения информации об ограниченных ключах.
messaging/payload-size-limit-exceeded Предоставленная полезная нагрузка сообщения превышает ограничения размера FCM . Для большинства сообщений ограничение составляет 4096 байт. Для сообщений, отправленных в темы, ограничение составляет 2048 байт. Общий размер полезных данных включает в себя как ключи, так и значения.
messaging/invalid-options Предоставлен недопустимый объект параметров сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-registration-token Предоставлен неверный регистрационный токен. Убедитесь, что он соответствует регистрационному токену, который клиентское приложение получает при регистрации в FCM . Не обрезайте и не добавляйте в него дополнительные символы.
messaging/registration-token-not-registered Предоставленный регистрационный токен не зарегистрирован. Ранее действующий регистрационный токен может быть отменен по ряду причин, в том числе:
  • Клиентское приложение отменило регистрацию в FCM .
  • Клиентское приложение было автоматически отменено. Это может произойти, если пользователь удаляет приложение или, на платформах Apple, если служба обратной связи APNs сообщает, что токен APNs недействителен.
  • Срок действия регистрационного токена истек. Например, Google может принять решение обновить регистрационные токены или срок действия токена APNs для устройств Apple может быть истек.
  • Клиентское приложение было обновлено, но новая версия не настроена на получение сообщений.
Во всех этих случаях удалите этот регистрационный токен и прекратите использовать его для отправки сообщений.
messaging/invalid-package-name Сообщение было адресовано регистрационному токену, имя пакета которого не соответствует предоставленному параметру restrictedPackageName .
messaging/message-rate-exceeded Скорость отправки сообщений определенной цели слишком высока. Уменьшите количество сообщений, отправляемых на это устройство или тему, и не повторяйте отправку сразу на эту цель.
messaging/device-message-rate-exceeded Скорость отправки сообщений на конкретное устройство слишком высока. Уменьшите количество сообщений, отправляемых на это устройство, и не повторяйте отправку на это устройство немедленно.
messaging/topics-message-rate-exceeded Частота сообщений подписчикам по определенной теме слишком высока. Уменьшите количество сообщений, отправляемых по этой теме, и не повторяйте отправку в эту тему немедленно.
messaging/too-many-topics Регистрационный токен подписан на максимальное количество тем и больше не может быть подписан.
messaging/invalid-apns-credentials Не удалось отправить сообщение, предназначенное для устройства Apple, поскольку требуемый SSL-сертификат APN не был загружен или срок его действия истек. Проверьте действительность ваших сертификатов разработки и производства.
messaging/mismatched-credential Учетные данные, используемые для аутентификации этого пакета SDK, не имеют разрешения на отправку сообщений на устройство, соответствующее предоставленному регистрационному токену. Убедитесь, что учетные данные и токен регистрации принадлежат одному и тому же проекту Firebase. См. документацию по проверке подлинности Firebase Admin SDK в разделе «Добавление Firebase в ваше приложение» .
messaging/authentication-error SDK не смог пройти аутентификацию на серверах FCM . Убедитесь, что вы аутентифицируете Firebase Admin SDK с помощью учетных данных, которые имеют необходимые разрешения для отправки сообщений FCM . См. документацию по проверке подлинности Firebase Admin SDK в разделе «Добавление Firebase в ваше приложение» .
messaging/server-unavailable Сервер FCM не смог вовремя обработать запрос. Вам следует повторить тот же запрос, но вы должны:
  • Учитывайте заголовок Retry-After , если он включен в ответ сервера соединений FCM .
  • Внедрите экспоненциальную отсрочку в механизме повторных попыток. Например, если вы подождали одну секунду перед первой повторной попыткой, подождите не менее двух секунд перед следующей, затем четыре секунды и так далее. Если вы отправляете несколько сообщений, задержите каждое из них независимо на дополнительную случайную величину, чтобы избежать одновременной отправки нового запроса для всех сообщений.
Отправители, вызывающие проблемы, рискуют попасть в черный список.
messaging/internal-error Сервер FCM обнаружил ошибку при попытке обработать запрос. Вы можете повторить тот же запрос, следуя требованиям, перечисленным в строке messaging/server-unavailable выше. Если ошибка не устранена, сообщите о проблеме в наш канал поддержки отчетов об ошибках .
messaging/unknown-error Возвращена неизвестная ошибка сервера. Дополнительные сведения см. в необработанном ответе сервера в сообщении об ошибке. Если вы получили эту ошибку, сообщите полное сообщение об ошибке в наш канал поддержки отчетов об ошибках .
,

Используя Firebase Admin SDK или протоколы сервера приложений FCM , вы можете создавать запросы сообщений и отправлять их на следующие типы целей:

  • Название темы
  • Состояние
  • Токен регистрации устройства
  • Имя группы устройств (только протокол)

Вы можете отправлять сообщения с полезными данными уведомления, состоящими из предопределенных полей, полезными данными с вашими собственными пользовательскими полями или сообщением, содержащим оба типа полезных данных. Дополнительные сведения см. в разделе Типы сообщений .

В примерах на этой странице показано, как отправлять уведомления с помощью Firebase Admin SDK (который поддерживает Node , Java , Python , C# и Go ) и протокола HTTP v1 .

Отправка сообщений на определенные устройства

Чтобы отправить на одно конкретное устройство, передайте токен регистрации устройства, как показано. См. информацию о настройке клиента для вашей платформы, чтобы узнать больше о регистрационных токенах.

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

В случае успеха каждый метод отправки возвращает идентификатор сообщения. Firebase Admin SDK возвращает строку идентификатора в формате projects/{project_id}/messages/{message_id} . Ответ протокола HTTP представляет собой один ключ JSON:

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

Отправка сообщений на несколько устройств

API-интерфейсы Admin FCM позволяют осуществлять многоадресную рассылку сообщений в список токенов регистрации устройств. Вы можете указать до 500 токенов регистрации устройств для каждого вызова.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Возвращаемое значение представляет собой список токенов, соответствующий порядку входных токенов. Это полезно, если вы хотите проверить, какие токены привели к ошибкам.

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

Ява

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

Питон

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

Идти

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

С#

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

Отправлять сообщения в темы

После того как вы создали тему, подписав на нее экземпляры клиентского приложения на стороне клиента или через серверный API , вы можете отправлять сообщения в тему. Если вы впервые создаете запросы на отправку для FCM , ознакомьтесь с руководством по вашей серверной среде и FCM для получения важной исходной информации и информации о настройке.

В логике отправки на серверной стороне укажите желаемое имя темы, как показано:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

Чтобы отправить сообщение по нескольким темам, укажите условие , которое представляет собой логическое выражение, определяющее целевые темы. Например, следующее условие отправит сообщения на устройства, подписанные на TopicA и TopicB или TopicC :

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

FCM сначала оценивает все условия в скобках, а затем оценивает выражение слева направо. В приведенном выше выражении пользователь, подписанный на какую-либо отдельную тему, не получает сообщение. Аналогично, пользователь, не подписанный на TopicA , не получит сообщение. Эти комбинации получают его:

  • TopicA и TopicB
  • TopicA и TopicC

В условное выражение можно включить до пяти тем.

Чтобы отправить условие:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

команда 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

Отправка сообщений группам устройств

Чтобы отправлять сообщения группам устройств, используйте API HTTP v1. Если вы в настоящее время отправляете сообщения группам устройств, используя устаревшие API отправки для HTTP или XMPP или любую из более старых версий Firebase Admin SDK для Node.js на основе устаревших протоколов, мы настоятельно рекомендуем вам перейти на API HTTP v1 при первой же возможности. Устаревшие API отправки будут отключены и удалены в июне 2024 года.

Отправка сообщений группе устройств очень похожа на отправку сообщений отдельному устройству: для авторизации запросов на отправку используется тот же метод. Установите в поле token ключ группового уведомления:

ОТДЫХ

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

команда 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

Отправьте пакет сообщений

Admin SDK поддерживают пакетную отправку сообщений. Вы можете сгруппировать до 500 сообщений в один пакет и отправить их все за один вызов API, что значительно улучшит производительность по сравнению с отправкой отдельных HTTP-запросов для каждого сообщения.

Эту функцию можно использовать для создания индивидуального набора сообщений и отправки их разным получателям, включая темы или определенные токены регистрации устройства. Используйте эту функцию, например, когда вам нужно одновременно отправлять сообщения разным аудиториям с немного разными деталями в теле сообщения.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Отправка прямых сообщений с включенной загрузкой (только для Android)

Вы можете отправлять сообщения на устройства в режиме прямой загрузки, используя HTTP v1 или устаревшие API-интерфейсы HTTP. Перед отправкой на устройства в режиме прямой загрузки убедитесь, что вы выполнили действия, позволяющие клиентским устройствам получать сообщения FCM в режиме прямой загрузки .

Отправка с использованием HTTP API FCM v1.

Запрос сообщения должен включать ключ "direct_boot_ok" : true в параметрах AndroidConfig тела запроса. Например:

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

Настраивайте сообщения на разных платформах

Firebase Admin SDK и HTTP-протокол FCM v1 позволяют вашим запросам сообщений устанавливать все поля, доступные в объекте message . Это включает в себя:

  • общий набор полей, которые будут интерпретироваться всеми экземплярами приложения, получающими сообщение.
  • наборы полей, зависящие от платформы, такие как AndroidConfig и WebpushConfig , интерпретируемые только экземплярами приложения, работающими на указанной платформе.

Блоки, специфичные для конкретной платформы, дают вам возможность настраивать сообщения для разных платформ, чтобы гарантировать их правильную обработку при получении. Серверная часть FCM учтет все указанные параметры и настроит сообщение для каждой платформы.

Когда использовать общие поля

Используйте общие поля, если вы:

  • Таргетинг на экземпляры приложений на всех платформах — Apple, Android и в Интернете.
  • Отправка сообщений в темы

Все экземпляры приложения, независимо от платформы, могут интерпретировать следующие общие поля:

Когда использовать поля, специфичные для платформы

Используйте поля, специфичные для платформы, если вы хотите:

  • Отправлять поля только на определенные платформы
  • Отправляйте поля, специфичные для платформы , в дополнение к общим полям.

Если вы хотите отправлять значения только на определенные платформы, не используйте общие поля; используйте поля, специфичные для платформы. Например, чтобы отправить уведомление только на платформы Apple и в Интернет, но не на Android, необходимо использовать два отдельных набора полей: один для Apple и один для Интернета.

Когда вы отправляете сообщения с определенными параметрами доставки , используйте поля для конкретной платформы, чтобы установить их. Если хотите, вы можете указать разные значения для каждой платформы. Однако даже если вы хотите установить по существу одно и то же значение для разных платформ, вы должны использовать поля, специфичные для платформы. Это связано с тем, что каждая платформа может интерпретировать значение немного по-разному — например, срок жизни на Android устанавливается как срок действия в секундах, а на Apple — как дата истечения срока действия.

Пример: уведомление с параметрами цвета и значка.

В этом примере запроса на отправку отправляется общий заголовок и содержимое уведомления на все платформы, но он также отправляет некоторые переопределения для конкретной платформы на устройства Android.

Для Android запрос устанавливает специальный значок и цвет для отображения на устройствах Android. Как отмечено в ссылке на AndroidNotification , цвет указывается в формате #rrggbb, а изображение должно представлять собой ресурс значка с возможностью рисования, локальный для приложения Android.

Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок двух устройств, одно из которых имеет собственный значок и цвет.

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

Ява

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

Питон

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',
)

Идти

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

С#

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с пользовательским изображением.

В следующем примере запроса на отправку на все платформы отправляется общий заголовок уведомления, а также изображение. Вот приблизительный визуальный эффект на устройстве пользователя:

Простое рисование изображения в уведомлении о показе

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с соответствующим действием по клику

В следующем примере запроса на отправку на все платформы отправляется общий заголовок уведомления, а также действие, которое приложение должно выполнить в ответ на взаимодействие пользователя с уведомлением. Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок касания пользователя, открывающего веб-страницу

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

ОТДЫХ

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

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Пример: уведомление с опциями локализации

В следующем примере запроса на отправку клиенту отправляются параметры локализации для отображения локализованных сообщений. Вот приблизительный визуальный эффект на устройстве пользователя:

Простой рисунок двух устройств, отображающих текст на английском и испанском языках.

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

ОТДЫХ

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"],
                    },
                 },
               },
             },
  },
}'

Подробную информацию о ключах, доступных в блоках для конкретной платформы в теле сообщения, см. в справочной документации HTTP v1.

Коды ошибок REST для API HTTP v1

Ответы об ошибках HTTP для API HTTP v1 содержат код ошибки, сообщение об ошибке и статус ошибки. Они также могут содержать массив details с более подробной информацией об ошибке.

Вот два примера ответов об ошибках:

Пример 1. Ответ об ошибке на запрос API HTTP v1 с недопустимым значением в сообщении данных.

{
  "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"
          }
        ]
      }
    ]
  }
}

Пример 2. Ответ об ошибке на запрос API HTTP v1 с недействительным токеном регистрации.

{
  "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"
      }
    ]
   }
}

Обратите внимание, что оба сообщения имеют одинаковый код и статус, но массив сведений содержит значения разных типов. Первый пример имеет тип type.googleapis.com/google.rpc.BadRequest что указывает на ошибку в значениях запроса. Во втором примере с типом type.googleapis.com/google.firebase.fcm.v1.FcmError имеется ошибка, специфичная для FCM. Для многих ошибок массив сведений содержит информацию, необходимую для отладки и поиска решения.

В следующей таблице перечислены коды ошибок REST API FCM v1 и их описания.

Код ошибки Описание и шаги решения
UNSPECIFIED_ERROR Нет больше информации об этой ошибке. Никто.
INVALID_ARGUMENT (код ошибки http = 400) Параметры запроса были недействительными. Расширение типа google.rpc.BadRequest возвращается, чтобы указать, какое поле было недействительным. Потенциальные причины включают в себя недействительную регистрацию, неверное имя пакета, сообщение слишком большое, неверный ключ данных, неверный TTL или другие неверные параметры.
Неверная регистрация : проверьте формат токена регистрации, который вы передаете на сервер. Убедитесь, что он соответствует токену регистрации, который клиентский приложение получает от регистрации в FCM. Не укройте токен и не добавляйте дополнительных символов.
Недопустимое имя пакета : убедитесь, что сообщение было адресовано токеном регистрации, имя пакета, имя пакета соответствует значению, передаваемому в запросе.
Сообщение Слишком большое : Убедитесь, что общий размер данных о полезной нагрузке, включенных в сообщение, не превышает пределов FCM: 4096 байтов для большинства сообщений или 2048 байтов в случае сообщений по темам. Это включает в себя как ключи, так и значения.
Неверный ключ данных : проверьте, что данные полезной нагрузки не содержат ключа (например, от или GCM, или любого значения, префиксированного Google), который используется внутри FCM. Обратите внимание, что некоторые слова (например, свернуть_ключ) также используются FCM, но разрешены в полезных данных, и в этом случае значение полезных данных будет переопределено значением FCM.
Неверный TTL : проверьте, что значение, используемое в TTL, представляет собой целое число, представляющее продолжительность за несколько секунд от 0 до 2419 200 (4 недели).
Неверные параметры : Убедитесь, что предоставленные параметры имеют правильное имя и тип.
UNREGISTERED (http -код ошибки = 404) экземпляр приложения был незарегистрирован от FCM. Обычно это означает, что используемый токен больше не является действительным, и необходимо использовать новый. Эта ошибка может быть вызвана отсутствующими токенами регистрации или незарегистрированными токенами.
Отсутствие регистрации : если цель сообщения является значением token , убедитесь, что запрос содержит токен регистрации.
Не зарегистрирован : существующий регистрационный токен может перестать быть действительным в ряде сценариев, включая:
- Если клиентское приложение нерегистрирует с FCM.
- Если клиентское приложение автоматически нерегистрировано, что может произойти, если пользователь удаляет приложение. Например, на iOS, если служба обратной связи APNS сообщила о токене APNS как недействительным.
- Если истекает токен регистрации (например, Google может решить обновить токены регистрации, или токен APNS истек для устройств iOS).
- Если клиентское приложение обновляется, но новая версия не настроена на получение сообщений.
Для всех этих случаев удалите этот токен регистрации с сервера приложений и прекратите использование его для отправки сообщений.
SENDER_ID_MISMATCH (код ошибки http = 403) Аутентифицированный идентификатор отправителя отличается от идентификатора отправителя для токена регистрации. Регистрационный токен связан с определенной группой отправителей. Когда клиентское приложение регистрируется для FCM, оно должно указать, каким отправителям разрешено отправлять сообщения. Вы должны использовать один из этих идентификаторов отправителя при отправке сообщений в клиентское приложение. Если вы переключитесь на другого отправителя, существующие токены регистрации не будут работать.
QUOTA_EXCEEDED (HTTP -код ошибки = 429) Отправка лимита превышена для цели сообщения. Расширение типа google.rpc.QuotaFailure возвращается, чтобы указать, какая квота была превышена. Эта ошибка может быть вызвана превышенной квотой скорости сообщений, превышенной квотой скорости сообщений устройства или превышенной квотой скорости тематических сообщений.
Скорость сообщений превышала : скорость отправки сообщений слишком высока. Вы должны снизить общую ставку, с которой вы отправляете сообщения. Используйте экспоненциальный откат с минимальной начальной задержкой в ​​1 минуту для повторения отклоненных сообщений.
Скорость сообщений устройства превышала : скорость сообщений на конкретное устройство слишком высока. См. Ограничение скорости сообщений на одно устройство . Уменьшите количество сообщений, отправленных на это устройство, и используйте экспоненциальный откат, чтобы повторно отправить отправку.
Скорость тематических сообщений превышена : скорость сообщений подписчикам на определенную тему слишком высока. Уменьшите количество сообщений, отправленных по этой теме, и используйте экспоненциальный откат с минимальной начальной задержкой в ​​1 минуту для повторения отправки.
UNAVAILABLE (код ошибки http = 503) Сервер перегружен. Сервер не мог обработать запрос вовремя. Повторно повторить тот же запрос, но вы должны:
- Почитайте заголовок повторного перерыва, если он включен в ответ с сервера соединений FCM.
- Реализуйте экспоненциальный отказ в вашем механизме повторной попытки. (Например, если вы ждали одну секунду перед первой попыткой, подождите как минимум за две секунды до следующей, затем 4 секунды и так далее). Если вы отправляете несколько сообщений, рассмотрите возможность применения дрожания. Для получения дополнительной информации см. Redling Rebries или проверьте панель панели состояния FCM , чтобы определить, есть ли какие -либо текущие сбои в обслуживании, влияющие на FCM. Отправители, которые вызывают проблемы, рискуют быть отклоненными.
INTERNAL (HTTP -код ошибки = 500) произошла неизвестная внутренняя ошибка. Сервер столкнулся с ошибкой при попытке обработать запрос. Вы можете повторно повторить тот же запрос после предложений при обработке повторений или проверки панели панели состояния FCM . Чтобы определить, существуют ли какие -либо текущие сбои в обслуживании, влияющие на FCM. Если ошибка сохраняется, пожалуйста, свяжитесь с поддержкой Firebase.
THIRD_PARTY_AUTH_ERROR (код ошибки http = 401) Сертификат APNS или клавиша Web Push Auth был недействительным или отсутствует. Сообщение, предназначенное для устройства iOS или регистрации в Интернете, не может быть отправлено. Проверьте обоснованность ваших учетных данных разработки и производства.

Коды ошибок администратора

В следующей таблице перечислены коды ошибок API FCM Firebase Admin и их описания, включая рекомендуемые шаги разрешения.

Код ошибки Шаги описания и разрешения
messaging/invalid-argument Неверный аргумент был предоставлен методу FCM . Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-recipient Предполагаемый получатель сообщения недействителен. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-payload Был предоставлен недопустимый объект полезной нагрузки сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-data-payload-key Полезная нагрузка сообщения данных содержит недопустимый ключ. См. Справочную документацию для DataMessagePayload для ограниченных ключей.
messaging/payload-size-limit-exceeded Предоставленная полезная нагрузка сообщения превышает пределы размера FCM . Предел составляет 4096 байтов для большинства сообщений. Для сообщений, отправленных на темы, предел составляет 2048 байт. Общий размер полезной нагрузки включает в себя как ключи, так и значения.
messaging/invalid-options Был предоставлен недопустимый объект параметров сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-registration-token Неверный регистрационный токен предоставлен. Убедитесь, что он соответствует токену регистрации, который клиентский приложение получает от регистрации в FCM . Не усекайте и не добавляйте в него дополнительные символы.
messaging/registration-token-not-registered Предоставленный регистрационный токен не зарегистрирован. Ранее действительный токен регистрации может быть незарегистрирован по разным причинам, в том числе:
  • Клиентское приложение не зарегистрировалось от FCM .
  • Клиентское приложение было автоматически незарегистрировано. Это может произойти, если пользователь удаляет приложение или на платформах Apple, если служба обратной связи APNS сообщила о токене APNS как недействительным.
  • Срок регистрации истек. Например, Google может решить обновить токены регистрации регистрации, или токен APNS, возможно, истек для устройств Apple.
  • Клиентское приложение было обновлено, но новая версия не настроена на получение сообщений.
Для всех этих случаев удалите этот токен регистрации и прекратите использование его для отправки сообщений.
messaging/invalid-package-name Сообщение было адресовано регистрационному токену, чье имя пакета не соответствует предоставленной опции restrictedPackageName .
messaging/message-rate-exceeded Скорость сообщений к конкретной цели слишком высока. Уменьшите количество сообщений, отправляемых на это устройство или тему, и не сразу повторите попытку отправки в эту цель.
messaging/device-message-rate-exceeded Скорость сообщений на конкретное устройство слишком высока. Уменьшите количество сообщений, отправленных на это устройство, и не сразу повторите попытку отправки на это устройство.
messaging/topics-message-rate-exceeded Скорость сообщений подписчикам на определенную тему слишком высок. Уменьшите количество сообщений, отправленных по этой теме, и не сразу повторите попытку отправки на эту тему.
messaging/too-many-topics Регистрационный токен был подписан на максимальное количество тем и не может быть подписан на большее.
messaging/invalid-apns-credentials Сообщение, предназначенное для устройства Apple, не может быть отправлено, потому что требуемый сертификат APNS SSL не был загружен или истек. Проверьте обоснованность ваших сертификатов разработки и производства.
messaging/mismatched-credential Учетные данные, используемые для аутентификации этого SDK, не имеют разрешения на отправку сообщений на устройство, соответствующее предоставляемому токен регистрации. Убедитесь, что оба учетные данные и токен регистрации принадлежат к одному и тому же проекту Firebase. См. Добавьте Firebase в ваше приложение для документации о том, как аутентифицировать подлинность Firebase Admin SDK .
messaging/authentication-error SDK не мог аутентифицировать на серверах FCM . Убедитесь, что вы аутентифицируете Firebase Admin SDK с учетом учетных данных, которые имеют надлежащие разрешения на отправку сообщений FCM . См. Добавьте Firebase в ваше приложение для документации о том, как аутентифицировать подлинность Firebase Admin SDK .
messaging/server-unavailable Сервер FCM не мог обработать запрос вовремя. Вы должны повторить тот же запрос, но вы должны:
  • Почитайте заголовок Retry-After если он включен в ответ от сервера соединений FCM .
  • Реализуйте экспоненциальный отступление в вашем механизме повторной попытки. Например, если вы ждали одну секунду до первой попытки, подождите как минимум за две секунды до следующей, затем четыре секунды и так далее. Если вы отправляете несколько сообщений, отложите каждое из них независимо на дополнительную случайную сумму, чтобы избежать выдачи нового запроса на все сообщения одновременно.
Отправители, которые вызывают проблемы, рискуют быть в черном списке.
messaging/internal-error Сервер FCM столкнулся с ошибкой, пытаясь обработать запрос. Вы можете повторить тот же запрос, следуя требованиям, перечисленным в строке messaging/server-unavailable . Если ошибка сохраняется, сообщите о проблеме нашего канала поддержки отчета об ошибках .
messaging/unknown-error Неизвестная ошибка сервера была возвращена. См. Реакцию RAW Server в сообщении об ошибке для получения более подробной информации. Если вы получите эту ошибку, сообщите о полном сообщении об ошибке в нашем канале поддержки отчета об ошибках .
,

Используя протоколы SDK SDK или FCM App Firebase Admin SDK или FCM, вы можете создавать запросы сообщений и отправить их в эти типы целей:

  • Имя темы
  • Состояние
  • Токен регистрации устройства
  • Название группы устройств (только протокол)

Вы можете отправлять сообщения с полезной нагрузкой уведомлений, состоящей из предопределенных полей, полезной нагрузки данных ваших собственных пользовательских полей или сообщения, содержащего оба типа полезной нагрузки. Смотрите типы сообщений для получения дополнительной информации.

Примеры на этой странице показывают, как отправлять сообщения уведомлений с использованием Firebase Admin SDK (который поддерживает узлы , Java , Python , C# и GO ) и протокол V1 HTTP .

Отправить сообщения на определенные устройства

Чтобы отправить на одно конкретное устройство, передайте токен регистрации устройства, как показано. См. Информацию о настройке клиента для вашей платформы, чтобы узнать больше о регистрационных токенах.

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

Команда 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

При успехе каждый метод отправки возвращает идентификатор сообщения. Firebase Admin SDK возвращает строку ID в Projects Format projects/{project_id}/messages/{message_id} . Ответ протокола HTTP - это единственный ключ JSON:

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

Отправить сообщения на несколько устройств

API ADIM FCM позволяют вам многоадресной рассылки в список токенов регистрации устройств. Вы можете указать до 500 токенов регистрации устройств на вызов.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Возвратное значение - это список токенов, который соответствует порядку входных токенов. Это полезно, когда вы хотите проверить, какие токены привели к ошибкам.

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

Ява

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

Питон

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

Идти

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

С#

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

Отправлять сообщения на темы

После того, как вы создали тему, либо подписав экземпляры клиентских приложений на тему на стороне клиента, либо через API сервера , вы можете отправлять сообщения на тему. Если это ваше первое время, когда вы отправляете запросы на FCM , см. Руководство по среде вашего сервера и FCM для важной информации и информации о настройке.

В вашей логике отправки на бэкэнд укажите желаемое имя темы, как показано:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

Команда 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

Чтобы отправить сообщение в комбинацию тем, укажите условие , которое является логическим выражением, которое указывает целевые темы. Например, следующее условие будет отправлять сообщения на устройства, которые подписаны на TopicA , а также TopicB или TopicC :

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

FCM сначала оценивает любые условия в скобках, а затем оценивает выражение слева направо. В приведенном выше выражении пользователь, подписанный на какую -либо отдельную тему, не получает сообщение. Аналогично, пользователь, который не подписывается на TopicA не получает сообщение. Эти комбинации получают это:

  • TopicA и TopicB
  • TopicA и TopicC

Вы можете включить до пяти тем в свое условное выражение.

Отправить в условие:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

Команда 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

Отправлять сообщения в группы устройств

Чтобы отправить сообщения в группы устройств, используйте API HTTP V1. Если вы в настоящее время отправляете в группы устройств, используя устаревшее устаревшее отправку API для HTTP или XMPP, или в любую из более старых версий Firebase Admin SDK для Node.js на основе протоколов устаревшего, мы настоятельно рекомендуем вам мигрировать в API HTTP V1 по самой ранней возможности. Наследия отправка API будет отключена и удалена в июне 2024 года.

Отправка сообщений в группу устройств очень похожа на отправку сообщений на отдельное устройство, используя тот же метод для авторизации запросов отправки . Установите поле token на ключ уведомления группы:

ОТДЫХ

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

Керл команда

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

Отправить партию сообщений

Admin SDKs поддерживает отправку сообщений в партиях. Вы можете группировать до 500 сообщений в одну партию и отправить их все в один вызов API, со значительным повышением производительности по сравнению с отправкой отдельных HTTP -запросов для каждого сообщения.

Эту функцию можно использовать для создания настраиваемого набора сообщений и отправки их разным получателям, включая темы или конкретные токены регистрации устройства. Используйте эту функцию, когда, например, вам необходимо одновременно отправлять сообщения в разные аудитории с немного разными деталями в теле сообщений.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Отправить прямые сообщения с поддержкой загрузки (только для Android)

Вы можете отправлять сообщения на устройства в режиме прямого загрузки, используя API HTTP V1 или Legacy HTTP. Перед отправкой на устройства в режиме прямого загрузки убедитесь, что вы выполнили шаги, чтобы разрешить клиентские устройства получать сообщения FCM в режиме прямого загрузки .

Отправить с помощью API FCM V1 HTTP

Запрос сообщения должен включать ключ "direct_boot_ok" : true в параметрах AndroidConfig органа запроса. Например:

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

Настроить сообщения на разных платформах

Firebase Admin SDK и протокол FCM V1 HTTP позволяют вашему сообщению устанавливать все поля, доступные в объекте message . Это включает в себя:

  • Общий набор полей, которые будут интерпретированы всеми экземплярами приложений, которые получают сообщение.
  • Платформа, набор полей, таких как AndroidConfig и WebpushConfig , интерпретируемые только экземплярами приложений, работающих на указанной платформе.

Блоки для конкретной платформы дают вам гибкость для настройки сообщений для различных платформ, чтобы убедиться, что они обрабатываются правильно при получении. Бэкэнд FCM будет учитывать все указанные параметры и настраивать сообщение для каждой платформы.

Когда использовать общие поля

Используйте общие поля, когда вы:

  • Нацеливание на экземпляры приложений на всех платформах - Apple, Android и Web
  • Отправка сообщений на темы

Все экземпляры приложений, независимо от платформы, могут интерпретировать следующие общие поля:

Когда использовать поля для конкретных платформ

Используйте поля, специфичные для платформы, когда вы хотите:

  • Отправить поля только на определенные платформы
  • Отправить поля для конкретной платформы в дополнение к общим полям

Всякий раз, когда вы хотите отправлять значения только на определенные платформы, не используйте общие поля; Используйте поля для конкретных платформ. Например, чтобы отправить уведомление только на платформы Apple и Интернет, но не на Android, вы должны использовать два отдельных набора полей, один для Apple и один для Интернета.

Когда вы отправляете сообщения с конкретными параметрами доставки , используйте поля для конкретной платформы для их установки. Вы можете указать разные значения на платформу, если хотите. Однако, даже если вы хотите установить по существу одинаковое значение на разных платформах, вы должны использовать поля для конкретной платформы. Это связано с тем, что каждая платформа может интерпретировать значение немного по-другому, например, время к жизни установлено на Android как время истечения срока действия, а на Apple это установлено как дата истечения срока действия.

Пример: Сообщение уведомлений с вариантами цвета и значка

В этом примере запрос отправки отправляет общее название уведомления и контент на все платформы, но также отправляет некоторые переопределения для устройств Android, специфичные для платформы.

Для Android запрос устанавливает специальный значок и цвет для отображения на устройствах Android. Как отмечено в ссылке на AndroidNotification , цвет указан в формате #RRGGBB, а изображение должно быть ресурсом для приложения для Android на рисовании.

Вот приближение визуального эффекта на устройство пользователя:

Простой рисунок двух устройств, с одним отображением настраиваемого значка и цвета

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

Ява

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

Питон

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',
)

Идти

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

С#

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

ОТДЫХ

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

См. Справочной документации HTTP V1 для получения полной информации о ключах, доступных в блоках для конкретных платформ в теле сообщений.

Пример: сообщение уведомления с пользовательским изображением

В следующем примере запрос отправки отправляет общее название уведомления на все платформы, но также отправляет изображение. Вот приближение визуального эффекта на устройство пользователя:

Простой рисунок изображения в уведомлении о дисплее

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

ОТДЫХ

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

См. Справочной документации HTTP V1 для получения полной информации о ключах, доступных в блоках для конкретных платформ в теле сообщений.

Пример: сообщение уведомления с соответствующим действием щелчка

В следующем примере запрос отправки отправляет общее название уведомления на все платформы, но также отправляет действие для приложения для выполнения в ответ на взаимодействие пользователя, взаимодействующее с уведомлением. Вот приближение визуального эффекта на устройство пользователя:

Простой рисунок пользователя нажмите на открытие веб -страницы

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

ОТДЫХ

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

См. Справочной документации HTTP V1 для получения полной информации о ключах, доступных в блоках для конкретных платформ в теле сообщений.

Пример: сообщение уведомления с параметрами локализации

В следующем примере запрос отправки отправляет параметры локализации для клиента для отображения локализованных сообщений. Вот приближение визуального эффекта на устройство пользователя:

Простой рисунок двух устройств, отображающих текст на английском и испанском языке

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

ОТДЫХ

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"],
                    },
                 },
               },
             },
  },
}'

См. Справочной документации HTTP V1 для получения полной информации о ключах, доступных в блоках для конкретных платформ в теле сообщений.

Коды ошибок отдыха для API HTTP V1

Ответы по ошибкам HTTP для API HTTP V1 содержат код ошибки, сообщение об ошибке и статус ошибки. Они также могут содержать массив details с более подробной информацией об ошибке.

Вот два ответа на ошибку образца:

Пример 1: Ответ об ошибке из запроса API HTTP V1 с неверным значением в сообщении данных

{
  "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"
          }
        ]
      }
    ]
  }
}

Пример 2: Ответ об ошибке из запроса API HTTP V1 с неверным токеном регистрации

{
  "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"
      }
    ]
   }
}

Обратите внимание, что оба сообщения имеют одинаковый код и статус, но массив деталей содержит значения в разных типах. Первый пример имеет тип type.googleapis.com/google.rpc.BadRequest указывающий ошибку в значениях запроса. Второй пример с типом type.googleapis.com/google.firebase.fcm.v1.FcmError имеет ошибку FCM. Для многих ошибок массив деталей содержит информацию, которая вам необходима для отладки, и найти разрешение.

В следующей таблице перечислены коды ошибок API FCM V1 REST и их описания.

Код ошибки Шаги описания и разрешения
UNSPECIFIED_ERROR Нет больше информации об этой ошибке. Никто.
INVALID_ARGUMENT (код ошибки http = 400) Параметры запроса были недействительными. Расширение типа google.rpc.BadRequest возвращается, чтобы указать, какое поле было недействительным. Потенциальные причины включают в себя недействительную регистрацию, неверное имя пакета, сообщение слишком большое, неверный ключ данных, неверный TTL или другие неверные параметры.
Неверная регистрация : проверьте формат токена регистрации, который вы передаете на сервер. Убедитесь, что он соответствует токену регистрации, который клиентский приложение получает от регистрации в FCM. Не укройте токен и не добавляйте дополнительных символов.
Недопустимое имя пакета : убедитесь, что сообщение было адресовано токеном регистрации, имя пакета, имя пакета соответствует значению, передаваемому в запросе.
Сообщение Слишком большое : Убедитесь, что общий размер данных о полезной нагрузке, включенных в сообщение, не превышает пределов FCM: 4096 байтов для большинства сообщений или 2048 байтов в случае сообщений по темам. Это включает в себя как ключи, так и значения.
Неверный ключ данных : проверьте, что данные полезной нагрузки не содержат ключа (например, от или GCM, или любого значения, префиксированного Google), который используется внутри FCM. Обратите внимание, что некоторые слова (например, свернуть_ключ) также используются FCM, но разрешены в полезных данных, и в этом случае значение полезных данных будет переопределено значением FCM.
Неверный TTL : проверьте, что значение, используемое в TTL, представляет собой целое число, представляющее продолжительность за несколько секунд от 0 до 2419 200 (4 недели).
Неверные параметры : Убедитесь, что предоставленные параметры имеют правильное имя и тип.
UNREGISTERED (http -код ошибки = 404) экземпляр приложения был незарегистрирован от FCM. Обычно это означает, что используемый токен больше не является действительным, и необходимо использовать новый. Эта ошибка может быть вызвана отсутствующими токенами регистрации или незарегистрированными токенами.
Отсутствие регистрации : если цель сообщения является значением token , убедитесь, что запрос содержит токен регистрации.
Не зарегистрирован : существующий регистрационный токен может перестать быть действительным в ряде сценариев, включая:
- Если клиентское приложение нерегистрирует с FCM.
- Если клиентское приложение автоматически нерегистрировано, что может произойти, если пользователь удаляет приложение. Например, на iOS, если служба обратной связи APNS сообщила о токене APNS как недействительным.
- Если истекает токен регистрации (например, Google может решить обновить токены регистрации, или токен APNS истек для устройств iOS).
- Если клиентское приложение обновляется, но новая версия не настроена на получение сообщений.
Для всех этих случаев удалите этот токен регистрации с сервера приложений и прекратите использование его для отправки сообщений.
SENDER_ID_MISMATCH (код ошибки http = 403) Аутентифицированный идентификатор отправителя отличается от идентификатора отправителя для токена регистрации. Регистрационный токен связан с определенной группой отправителей. Когда клиентское приложение регистрируется для FCM, оно должно указать, каким отправителям разрешено отправлять сообщения. Вы должны использовать один из этих идентификаторов отправителя при отправке сообщений в клиентское приложение. Если вы переключитесь на другого отправителя, существующие токены регистрации не будут работать.
QUOTA_EXCEEDED (HTTP -код ошибки = 429) Отправка лимита превышена для цели сообщения. Расширение типа google.rpc.QuotaFailure возвращается, чтобы указать, какая квота была превышена. Эта ошибка может быть вызвана превышенной квотой скорости сообщений, превышенной квотой скорости сообщений устройства или превышенной квотой скорости тематических сообщений.
Скорость сообщений превышала : скорость отправки сообщений слишком высока. Вы должны снизить общую ставку, с которой вы отправляете сообщения. Используйте экспоненциальный откат с минимальной начальной задержкой в ​​1 минуту для повторения отклоненных сообщений.
Скорость сообщений устройства превышала : скорость сообщений на конкретное устройство слишком высока. См. Ограничение скорости сообщений на одно устройство . Уменьшите количество сообщений, отправленных на это устройство, и используйте экспоненциальный откат, чтобы повторно отправить отправку.
Скорость тематических сообщений превышена : скорость сообщений подписчикам на определенную тему слишком высока. Уменьшите количество сообщений, отправленных по этой теме, и используйте экспоненциальный откат с минимальной начальной задержкой в ​​1 минуту для повторения отправки.
UNAVAILABLE (код ошибки http = 503) Сервер перегружен. Сервер не мог обработать запрос вовремя. Повторно повторить тот же запрос, но вы должны:
- Почитайте заголовок повторного перерыва, если он включен в ответ с сервера соединений FCM.
- Реализуйте экспоненциальный отказ в вашем механизме повторной попытки. (Например, если вы ждали одну секунду перед первой попыткой, подождите как минимум за две секунды до следующей, затем 4 секунды и так далее). Если вы отправляете несколько сообщений, рассмотрите возможность применения дрожания. Для получения дополнительной информации см. Redling Rebries или проверьте панель панели состояния FCM , чтобы определить, есть ли какие -либо текущие сбои в обслуживании, влияющие на FCM. Отправители, которые вызывают проблемы, рискуют быть отклоненными.
INTERNAL (HTTP -код ошибки = 500) произошла неизвестная внутренняя ошибка. Сервер столкнулся с ошибкой при попытке обработать запрос. Вы можете повторно повторить тот же запрос после предложений при обработке повторений или проверки панели панели состояния FCM . Чтобы определить, существуют ли какие -либо текущие сбои в обслуживании, влияющие на FCM. Если ошибка сохраняется, пожалуйста, свяжитесь с поддержкой Firebase.
THIRD_PARTY_AUTH_ERROR (код ошибки http = 401) Сертификат APNS или клавиша Web Push Auth был недействительным или отсутствует. Сообщение, предназначенное для устройства iOS или регистрации в Интернете, не может быть отправлено. Проверьте обоснованность ваших учетных данных разработки и производства.

Коды ошибок администратора

В следующей таблице перечислены коды ошибок API FCM Firebase Admin и их описания, включая рекомендуемые шаги разрешения.

Код ошибки Шаги описания и разрешения
messaging/invalid-argument Неверный аргумент был предоставлен методу FCM . Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-recipient Предполагаемый получатель сообщения недействителен. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-payload Был предоставлен недопустимый объект полезной нагрузки сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-data-payload-key Полезная нагрузка сообщения данных содержит недопустимый ключ. См. Справочную документацию для DataMessagePayload для ограниченных ключей.
messaging/payload-size-limit-exceeded Предоставленная полезная нагрузка сообщения превышает пределы размера FCM . Предел составляет 4096 байтов для большинства сообщений. Для сообщений, отправленных на темы, предел составляет 2048 байт. Общий размер полезной нагрузки включает в себя как ключи, так и значения.
messaging/invalid-options Был предоставлен недопустимый объект параметров сообщения. Сообщение об ошибке должно содержать дополнительную информацию.
messaging/invalid-registration-token Неверный регистрационный токен предоставлен. Убедитесь, что он соответствует токену регистрации, который клиентский приложение получает от регистрации в FCM . Не усекайте и не добавляйте в него дополнительные символы.
messaging/registration-token-not-registered Предоставленный регистрационный токен не зарегистрирован. Ранее действительный токен регистрации может быть незарегистрирован по разным причинам, в том числе:
  • Клиентское приложение не зарегистрировалось от FCM .
  • Клиентское приложение было автоматически незарегистрировано. Это может произойти, если пользователь удаляет приложение или на платформах Apple, если служба обратной связи APNS сообщила о токене APNS как недействительным.
  • Срок регистрации истек. Например, Google может решить обновить токены регистрации регистрации, или токен APNS, возможно, истек для устройств Apple.
  • Клиентское приложение было обновлено, но новая версия не настроена на получение сообщений.
Для всех этих случаев удалите этот токен регистрации и прекратите использование его для отправки сообщений.
messaging/invalid-package-name Сообщение было адресовано регистрационному токену, чье имя пакета не соответствует предоставленной опции restrictedPackageName .
messaging/message-rate-exceeded Скорость сообщений к конкретной цели слишком высока. Уменьшите количество сообщений, отправляемых на это устройство или тему, и не сразу повторите попытку отправки в эту цель.
messaging/device-message-rate-exceeded Скорость сообщений на конкретное устройство слишком высока. Уменьшите количество сообщений, отправленных на это устройство, и не сразу повторите попытку отправки на это устройство.
messaging/topics-message-rate-exceeded Скорость сообщений подписчикам на определенную тему слишком высок. Уменьшите количество сообщений, отправленных по этой теме, и не сразу повторите попытку отправки на эту тему.
messaging/too-many-topics Регистрационный токен был подписан на максимальное количество тем и не может быть подписан на большее.
messaging/invalid-apns-credentials Сообщение, предназначенное для устройства Apple, не может быть отправлено, потому что требуемый сертификат APNS SSL не был загружен или истек. Проверьте обоснованность ваших сертификатов разработки и производства.
messaging/mismatched-credential Учетные данные, используемые для аутентификации этого SDK, не имеют разрешения на отправку сообщений на устройство, соответствующее предоставляемому токен регистрации. Убедитесь, что оба учетные данные и токен регистрации принадлежат к одному и тому же проекту Firebase. См. Добавьте Firebase в ваше приложение для документации о том, как аутентифицировать подлинность Firebase Admin SDK .
messaging/authentication-error SDK не мог аутентифицировать на серверах FCM . Убедитесь, что вы аутентифицируете Firebase Admin SDK с учетом учетных данных, которые имеют надлежащие разрешения на отправку сообщений FCM . См. Добавьте Firebase в ваше приложение для документации о том, как аутентифицировать подлинность Firebase Admin SDK .
messaging/server-unavailable Сервер FCM не мог обработать запрос вовремя. Вы должны повторить тот же запрос, но вы должны:
  • Почитайте заголовок Retry-After если он включен в ответ от сервера соединений FCM .
  • Реализуйте экспоненциальный отступление в вашем механизме повторной попытки. Например, если вы ждали одну секунду до первой попытки, подождите как минимум за две секунды до следующей, затем четыре секунды и так далее. Если вы отправляете несколько сообщений, отложите каждое из них независимо на дополнительную случайную сумму, чтобы избежать выдачи нового запроса на все сообщения одновременно.
Отправители, которые вызывают проблемы, рискуют быть в черном списке.
messaging/internal-error Сервер FCM столкнулся с ошибкой, пытаясь обработать запрос. Вы можете повторить тот же запрос, следуя требованиям, перечисленным в строке messaging/server-unavailable . Если ошибка сохраняется, сообщите о проблеме нашего канала поддержки отчета об ошибках .
messaging/unknown-error Неизвестная ошибка сервера была возвращена. См. Реакцию RAW Server в сообщении об ошибке для получения более подробной информации. Если вы получите эту ошибку, сообщите о полном сообщении об ошибке в нашем канале поддержки отчета об ошибках .
,

Используя протоколы SDK SDK или FCM App Firebase Admin SDK или FCM, вы можете создавать запросы сообщений и отправить их в эти типы целей:

  • Имя темы
  • Состояние
  • Токен регистрации устройства
  • Название группы устройств (только протокол)

Вы можете отправлять сообщения с полезной нагрузкой уведомлений, состоящей из предопределенных полей, полезной нагрузки данных ваших собственных пользовательских полей или сообщения, содержащего оба типа полезной нагрузки. Смотрите типы сообщений для получения дополнительной информации.

Примеры на этой странице показывают, как отправлять сообщения уведомлений с использованием Firebase Admin SDK (который поддерживает узлы , Java , Python , C# и GO ) и протокол V1 HTTP .

Отправить сообщения на определенные устройства

Чтобы отправить на одно конкретное устройство, передайте токен регистрации устройства, как показано. См. Информацию о настройке клиента для вашей платформы, чтобы узнать больше о регистрационных токенах.

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

cURL command:

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

On success, each send method returns a message ID. The Firebase Admin SDK returns the ID string in the format projects/{project_id}/messages/{message_id} . The HTTP protocol response is a single JSON key:

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

Send messages to multiple devices

The Admin FCM APIs allow you to multicast a message to a list of device registration tokens. You can specify up to 500 device registration tokens per invocation.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

The return value is a list of tokens that corresponds to the order of the input tokens. This is useful when you want to check which tokens resulted in errors.

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

Ява

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

Питон

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

Идти

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

С#

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

Send messages to topics

After you have created a topic, either by subscribing client app instances to the topic on the client side or via the server API , you can send messages to the topic. If this is your first time building send requests for FCM , see the guide to your server environment and FCM for important background and setup information.

In your sending logic on the backend, specify the desired topic name as shown:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

cURL command:

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

To send a message to a combination of topics, specify a condition , which is a boolean expression that specifies the target topics. For example, the following condition will send messages to devices that are subscribed to TopicA and either TopicB or TopicC :

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

FCM first evaluates any conditions in parentheses, and then evaluates the expression from left to right. In the above expression, a user subscribed to any single topic does not receive the message. Likewise, a user who does not subscribe to TopicA does not receive the message. These combinations do receive it:

  • TopicA and TopicB
  • TopicA and TopicC

You can include up to five topics in your conditional expression.

To send to a condition:

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

Ява

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

Питон

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

Идти

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

С#

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

ОТДЫХ

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

cURL command:

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

Send messages to device groups

To send messages to device groups, use the HTTP v1 API. If you are currently sending to device groups using the deprecated legacy send APIs for HTTP or XMPP, or any of the older versions of the Firebase Admin SDK for Node.js based on the legacy protocols, we strongly recommend that you migrate to the HTTP v1 API at the earliest opportunity. The legacy send APIs will be disabled and removed in June 2024.

Sending messages to a device group is very similar to sending messages to an individual device, using the same method to authorize send requests . Set the token field to the group notification key:

ОТДЫХ

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

cURL command

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

Send a batch of messages

The Admin SDKs support sending messages in batches. You can group up to 500 messages into a single batch and send them all in a single API call, with significant performance improvement over sending separate HTTP requests for each message.

This feature can be used to build a customized set of messages and send them to different recipients, including topics or specific device registration tokens. Use this feature when, for example, you need to simultaneously send messages to different audiences with slightly different details in the message body.

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');
  });

Ява

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

Питон

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

Идти

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

С#

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

Send direct boot-enabled messages (Android only)

You can send messages to devices in direct boot mode using the HTTP v1 or legacy HTTP APIs. Before sending to devices in direct boot mode, make sure you have completed the steps to enable client devices to receive FCM messages in direct boot mode .

Send using the FCM v1 HTTP API

The message request must include the key "direct_boot_ok" : true in the AndroidConfig options of the request body. Например:

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

Customize messages across platforms

The Firebase Admin SDK and the FCM v1 HTTP protocol both allow your message requests to set all fields available in the message object. Это включает в себя:

  • a common set of fields to be interpreted by all app instances that receive the message.
  • platform-specific sets of fields, such as AndroidConfig and WebpushConfig , interpreted only by app instances running on the specified platform.

Platform-specific blocks give you flexibility to customize messages for different platforms to ensure that they are handled correctly when received. The FCM backend will take all specified parameters into account and customize the message for each platform.

When to use common fields

Use common fields when you're:

  • Targeting app instances on all platforms — Apple, Android, and web
  • Sending messages to topics

All app instances, regardless of platform, can interpret the following common fields:

When to use platform-specific fields

Use platform-specific fields when you want to:

  • Send fields only to particular platforms
  • Send platform-specific fields in addition to the common fields

Whenever you want to send values only to particular platforms, don't use common fields; use platform-specific fields. For example, to send a notification only to Apple platforms and web but not to Android, you must use two separate sets of fields, one for Apple and one for web.

When you are sending messages with specific delivery options , use platform-specific fields to set them. You can specify different values per platform if you want. However, even when you want to set essentially the same value across platforms, you must use platform-specific fields. This is because each platform may interpret the value slightly differently—for example, time-to-live is set on Android as an expiration time in seconds, while on Apple it is set as an expiration date .

Example: notification message with color and icon options

This example send request sends a common notification title and content to all platforms, but it also sends some platform-specific overrides to Android devices.

For Android, the request sets a special icon and color to display on Android devices. As noted in the reference for AndroidNotification , the color is specified in #rrggbb format, and the image must be a drawable icon resource local to the Android app.

Here's an approximation of the visual effect on a user's device:

Simple drawing of two devices, with one displaying a custom icon and color

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

Ява

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

Питон

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',
)

Идти

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

С#

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

ОТДЫХ

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

See the HTTP v1 reference documentation for complete detail on the keys available in platform-specific blocks in the message body.

Example: notification message with a custom image

The following example send request sends a common notification title to all platforms, but it also sends an image. Here's an approximation of the visual effect on a user's device:

Simple drawing of an image in a display notification

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

ОТДЫХ

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

See the HTTP v1 reference documentation for complete detail on the keys available in platform-specific blocks in the message body.

Example: notification message with an associated click action

The following example send request sends a common notification title to all platforms, but it also sends an action for the app to perform in response to user interacting with the notification. Here's an approximation of the visual effect on a user's device:

Simple drawing of a user tap opening a web page

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

ОТДЫХ

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

See the HTTP v1 reference documentation for complete detail on the keys available in platform-specific blocks in the message body.

Example: notification message with localization options

The following example send request sends localization options for the client to display localized messages. Here's an approximation of the visual effect on a user's device:

Simple drawing of two devices displaying text in English and Spanish

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

ОТДЫХ

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"],
                    },
                 },
               },
             },
  },
}'

See the HTTP v1 reference documentation for complete detail on the keys available in platform-specific blocks in the message body.

REST error codes for the HTTP v1 API

HTTP error responses for the HTTP v1 API contain an error code, an error message, and error status. They may also contain a details array with more details on the error.

Here are two sample error responses:

Example 1: Error response from an HTTP v1 API request with an invalid value in a data message

{
  "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"
          }
        ]
      }
    ]
  }
}

Example 2: Error response from an HTTP v1 API request with an invalid registration token

{
  "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"
      }
    ]
   }
}

Note that both messages have the same code and status, but the details array contains values in different types. The first example has type type.googleapis.com/google.rpc.BadRequest indicating an error in request values. The second example with type type.googleapis.com/google.firebase.fcm.v1.FcmError has an FCM specific error. For many errors, the details array contains the information you'll need to debug and find a resolution.

The following table lists the FCM v1 REST API error codes and their descriptions.

Error Code Description and Resolution Steps
UNSPECIFIED_ERROR No more information is available about this error. Никто.
INVALID_ARGUMENT (HTTP error code = 400) Request parameters were invalid. An extension of type google.rpc.BadRequest is returned to specify which field was invalid. Potential causes include invalid registration, invalid package name, message too big, invalid data key, invalid TTL, or other invalid parameters.
Invalid registration : Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with FCM. Do not truncate the token or add additional characters.
Invalid package name : Make sure the message was addressed to a registration token whose package name matches the value passed in the request.
Message too big : Check that the total size of the payload data included in a message does not exceed FCM limits: 4096 bytes for most messages, or 2048 bytes in the case of messages to topics. This includes both the keys and the values.
Invalid data key : Check that the payload data does not contain a key (such as from, or gcm, or any value prefixed by google) that is used internally by FCM. Обратите внимание, что некоторые слова (например, свернуть_ключ) также используются FCM, но разрешены в полезных данных, и в этом случае значение полезных данных будет переопределено значением FCM.
Invalid TTL : Check that the value used in ttl is an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks).
Invalid parameters : Check that the provided parameters have the right name and type.
UNREGISTERED (HTTP error code = 404) App instance was unregistered from FCM. This usually means that the token used is no longer valid and a new one must be used. This error can be caused by missing registration tokens, or unregistered tokens.
Missing Registration : If the message's target is a token value, check that the request contains a registration token.
Not registered : An existing registration token may cease to be valid in a number of scenarios, including:
- If the client app unregisters with FCM.
- If the client app is automatically unregistered, which can happen if the user uninstalls the application. For example, on iOS, if the APNs Feedback Service reported the APNs token as invalid.
- If the registration token expires (for example, Google might decide to refresh registration tokens, or the APNs token has expired for iOS devices).
- If the client app is updated but the new version is not configured to receive messages.
For all these cases, remove this registration token from the app server and stop using it to send messages.
SENDER_ID_MISMATCH (HTTP error code = 403) The authenticated sender ID is different from the sender ID for the registration token. A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration tokens won't work.
QUOTA_EXCEEDED (HTTP error code = 429) Sending limit exceeded for the message target. An extension of type google.rpc.QuotaFailure is returned to specify which quota was exceeded. This error can be caused by exceeded message rate quota, exceeded device message rate quota, or exceeded topic message rate quota.
Message rate exceeded : The sending rate of messages is too high. You must reduce the overall rate at which you send messages. Use exponential backoff with a minimum initial delay of 1 minute to retry rejected messages.
Device message rate exceeded : The rate of messages to a particular device is too high. See message rate limit to a single device . Reduce the number of messages sent to this device and use exponential backoff to retry sending.
Topic message rate exceeded : The rate of messages to subscribers to a particular topic is too high. Reduce the number of messages sent for this topic and use exponential backoff with a minimum initial delay of 1 minute to retry sending.
UNAVAILABLE (HTTP error code = 503) The server is overloaded. The server couldn't process the request in time. Retry the same request, but you must:
- Honor the Retry-After header if it is included in the response from the FCM Connection Server.
- Implement exponential backoff in your retry mechanism. (eg if you waited one second before the first retry, wait at least two seconds before the next one, then 4 seconds and so on). If you're sending multiple messages, consider applying jittering. For more information, see Handling retries , or check the FCM status dashboard to identify if there are any ongoing service disruptions affecting FCM. Senders that cause problems risk being denylisted.
INTERNAL (HTTP error code = 500) An unknown internal error occurred. The server encountered an error while trying to process the request. You could retry the same request following suggestions in Handling retries or checking the FCM status dashboard . to identify if there are any ongoing service disruptions affecting FCM. If the error persists, please contact Firebase support.
THIRD_PARTY_AUTH_ERROR (HTTP error code = 401) APNs certificate or web push auth key was invalid or missing. A message targeted to an iOS device or a web push registration could not be sent. Check the validity of your development and production credentials.

Admin error codes

The following table lists the Firebase Admin FCM API error codes and their descriptions, including recommended resolution steps.

Error Code Description and Resolution Steps
messaging/invalid-argument An invalid argument was provided to an FCM method. The error message should contain additional information.
messaging/invalid-recipient The intended message recipient is invalid. The error message should contain additional information.
messaging/invalid-payload An invalid message payload object was provided. The error message should contain additional information.
messaging/invalid-data-payload-key The data message payload contains an invalid key. See the reference documentation for DataMessagePayload for restricted keys.
messaging/payload-size-limit-exceeded The provided message payload exceeds the FCM size limits. The limit is 4096 bytes for most messages. For messages sent to topics, the limit is 2048 bytes. The total payload size includes both keys and values.
messaging/invalid-options An invalid message options object was provided. The error message should contain additional information.
messaging/invalid-registration-token Invalid registration token provided. Make sure it matches the registration token the client app receives from registering with FCM . Do not truncate or add additional characters to it.
messaging/registration-token-not-registered The provided registration token is not registered. A previously valid registration token can be unregistered for a variety of reasons, including:
  • The client app unregistered itself from FCM .
  • The client app was automatically unregistered. This can happen if the user uninstalls the application or, on Apple platforms, if the APNs Feedback Service reported the APNs token as invalid.
  • The registration token expired. For example, Google might decide to refresh registration tokens or the APNs token may have expired for Apple devices.
  • The client app was updated, but the new version is not configured to receive messages.
For all these cases, remove this registration token and stop using it to send messages.
messaging/invalid-package-name The message was addressed to a registration token whose package name does not match the provided restrictedPackageName option.
messaging/message-rate-exceeded The rate of messages to a particular target is too high. Reduce the number of messages sent to this device or topic and do not immediately retry sending to this target.
messaging/device-message-rate-exceeded The rate of messages to a particular device is too high. Reduce the number of messages sent to this device and do not immediately retry sending to this device.
messaging/topics-message-rate-exceeded The rate of messages to subscribers to a particular topic is too high. Reduce the number of messages sent for this topic, and do not immediately retry sending to this topic.
messaging/too-many-topics A registration token has been subscribed to the maximum number of topics and cannot be subscribed to any more.
messaging/invalid-apns-credentials A message targeted to an Apple device could not be sent because the required APNs SSL certificate was not uploaded or has expired. Check the validity of your development and production certificates.
messaging/mismatched-credential The credential used to authenticate this SDK does not have permission to send messages to the device corresponding to the provided registration token. Make sure the credential and registration token both belong to the same Firebase project. See Add Firebase to your app for documentation on how to authenticate the Firebase Admin SDK s.
messaging/authentication-error The SDK could not authenticate to the FCM servers. Make sure you authenticate the Firebase Admin SDK with a credential which has the proper permissions to send FCM messages. See Add Firebase to your app for documentation on how to authenticate the Firebase Admin SDK s.
messaging/server-unavailable The FCM server could not process the request in time. You should retry the same request, but you must:
  • Honor the Retry-After header if it is included in the response from the FCM Connection Server.
  • Implement exponential back-off in your retry mechanism. For example, if you waited one second before the first retry, wait at least two seconds before the next one, then four seconds, and so on. If you're sending multiple messages, delay each one independently by an additional random amount to avoid issuing a new request for all messages at the same time.
Senders that cause problems risk being blacklisted.
messaging/internal-error The FCM server encountered an error while trying to process the request. You could retry the same request following the requirements listed in the messaging/server-unavailable row above. If the error persists, please report the problem to our Bug Report support channel.
messaging/unknown-error An unknown server error was returned. See the raw server response in the error message for more details. If you receive this error, please report the full error message to our Bug Report support channel.