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

Используя протоколы 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

При успешном выполнении каждый метод 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

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

Отправка сообщений группе устройств очень похожа на отправку сообщений на отдельное устройство, используя тот же метод для авторизации запросов на отправку . Установите поле 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 или устаревших HTTP API. Перед отправкой на устройства в режиме прямой загрузки убедитесь, что вы выполнили шаги, чтобы разрешить клиентским устройствам получать сообщения FCM в режиме прямой загрузки .

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

Запрос сообщения должен включать ключ "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 и веб
  • Отправка сообщений по темам

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

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

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

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

Если вы хотите отправить значения только на определенные платформы, не используйте общие поля; используйте поля, специфичные для платформы. Например, чтобы отправить уведомление только на платформы 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 для HTTP v1 API

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

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

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

{
  "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: Ошибка ответа на запрос HTTP v1 API с недействительным токеном регистрации

{
  "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 байт в случае сообщений в темы. Сюда входят как ключи, так и значения.
Недопустимый ключ данных : проверьте, что данные полезной нагрузки не содержат ключ (например, from, или gcm, или любое значение с префиксом google), который используется внутри FCM. Обратите внимание, что некоторые слова (например, collapse_key) также используются FCM, но разрешены в полезной нагрузке, и в этом случае значение полезной нагрузки будет переопределено значением FCM.
Недопустимый TTL : проверьте, является ли значение, используемое в ttl, целым числом, представляющим длительность в секундах от 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 или ключ аутентификации web push недействителен или отсутствует. Не удалось отправить сообщение, нацеленное на устройство iOS или веб-push-регистрацию. Проверьте действительность ваших учетных данных для разработки и производства.

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

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

Код ошибки Описание и шаги по решению
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 s.
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 выше. Если ошибка повторяется, сообщите о проблеме в наш канал поддержки Bug Report .
messaging/unknown-error Возвращена неизвестная ошибка сервера. Для получения более подробной информации см. необработанный ответ сервера в сообщении об ошибке. Если вы получили эту ошибку, отправьте полное сообщение об ошибке на наш канал поддержки Bug Report .