使用 Firebase Admin SDK 或 FCM 应用服务器协议,您可以构建消息请求并将它们发送到这些类型的目标:
- 主题名称
- 健康)状况
- 设备注册令牌
- 设备组名称(仅适用于 Node.js 的旧协议和 Firebase Admin SDK)
您可以使用由预定义字段组成的通知有效负载、您自己的用户定义字段的数据有效负载或包含两种类型有效负载的消息来发送消息。有关详细信息,请参阅消息类型。
本页中的示例展示了如何使用 Firebase Admin SDK(支持Node 、 Java 、 Python 、 C#和Go )和v1 HTTP 协议发送通知消息。还有通过旧版 HTTP 和 XMPP 协议发送消息的指南。
向特定设备发送消息
要发送到单个特定设备,请如图所示传递设备的注册令牌。请参阅您的平台的客户端设置信息以了解有关注册令牌的更多信息。
节点.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);
Python
# This registration token comes from the client FCM SDKs.
registration_token = 'YOUR_REGISTRATION_TOKEN'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
token=registration_token,
)
# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
去
// Obtain a messaging.Client from the App.
ctx := context.Background()
client, err := app.Messaging(ctx)
if err != nil {
log.Fatalf("error getting Messaging client: %v\n", err)
}
// This registration token comes from the client FCM SDKs.
registrationToken := "YOUR_REGISTRATION_TOKEN"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Token: registrationToken,
}
// Send a message to the device corresponding to the provided
// registration token.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
C#
// This registration token comes from the client FCM SDKs.
var registrationToken = "YOUR_REGISTRATION_TOKEN";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Token = registrationToken,
};
// Send a message to the device corresponding to the provided
// registration token.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
休息
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 -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
成功时,每个发送方法都会返回一个消息 ID。 Firebase Admin SDK 以projects/{project_id}/messages/{message_id}
格式返回 ID 字符串。 HTTP 协议响应是单个 JSON 键:
{
"name":"projects/myproject-b5ae1/messages/0:1500415314455276%31bd1c9631bd1c96"
}
向多个设备发送消息
REST API 和 Admin FCM API 允许您将消息多播到设备注册令牌列表。每次调用最多可以指定 500 个设备注册令牌。
节点.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");
Python
# Create a list containing up to 500 registration tokens.
# These registration tokens come from the client FCM SDKs.
registration_tokens = [
'YOUR_REGISTRATION_TOKEN_1',
# ...
'YOUR_REGISTRATION_TOKEN_N',
]
message = messaging.MulticastMessage(
data={'score': '850', 'time': '2:45'},
tokens=registration_tokens,
)
response = messaging.send_multicast(message)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))
去
// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
"YOUR_REGISTRATION_TOKEN_1",
// ...
"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Tokens: registrationTokens,
}
br, err := client.SendMulticast(context.Background(), message)
if err != nil {
log.Fatalln(err)
}
// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)
C#
// Create a list containing up to 500 registration tokens.
// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
"YOUR_REGISTRATION_TOKEN_1",
// ...
"YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
Tokens = registrationTokens,
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
};
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(message);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");
休息
构建 HTTP 批量请求:
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"FCM Message",
"body":"This is an FCM notification message!"
}
}
}
...
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"cR1rjyj4_Kc:APA91bGusqbypSuMdsh7jSNrW4nzsM...",
"notification":{
"title":"FCM Message",
"body":"This is an FCM notification message!"
}
}
}
--subrequest_boundary--
将请求保存到文件中(在此示例中为 batch_request.txt)。然后使用 cURL 命令:
curl --data-binary @batch_request.txt -H 'Content-Type: multipart/mixed; boundary="subrequest_boundary"' -H 'Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA' https://fcm.googleapis.com/batch
对于 Firebase Admin SDK,此操作在后台使用sendAll()
API,如示例中所示。返回值是BatchResponse
,其响应列表对应于输入标记的顺序。当您想检查哪些标记导致错误时,这很有用。
节点.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);
}
Python
# These registration tokens come from the client FCM SDKs.
registration_tokens = [
'YOUR_REGISTRATION_TOKEN_1',
# ...
'YOUR_REGISTRATION_TOKEN_N',
]
message = messaging.MulticastMessage(
data={'score': '850', 'time': '2:45'},
tokens=registration_tokens,
)
response = messaging.send_multicast(message)
if response.failure_count > 0:
responses = response.responses
failed_tokens = []
for idx, resp in enumerate(responses):
if not resp.success:
# The order of responses corresponds to the order of the registration tokens.
failed_tokens.append(registration_tokens[idx])
print('List of tokens that caused failures: {0}'.format(failed_tokens))
去
// Create a list containing up to 500 registration tokens.
// This registration tokens come from the client FCM SDKs.
registrationTokens := []string{
"YOUR_REGISTRATION_TOKEN_1",
// ...
"YOUR_REGISTRATION_TOKEN_n",
}
message := &messaging.MulticastMessage{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Tokens: registrationTokens,
}
br, err := client.SendMulticast(context.Background(), message)
if err != nil {
log.Fatalln(err)
}
if br.FailureCount > 0 {
var failedTokens []string
for idx, resp := range br.Responses {
if !resp.Success {
// The order of responses corresponds to the order of the registration tokens.
failedTokens = append(failedTokens, registrationTokens[idx])
}
}
fmt.Printf("List of tokens that caused failures: %v\n", failedTokens)
}
C#
// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
"YOUR_REGISTRATION_TOKEN_1",
// ...
"YOUR_REGISTRATION_TOKEN_n",
};
var message = new MulticastMessage()
{
Tokens = registrationTokens,
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
};
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(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}");
}
休息
每个发送子发送返回一个响应。响应由以--batch_
开头的响应边界字符串分隔。
--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q
Content-Type: application/http
Content-ID: response-
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
"name": "projects/35006771263/messages/0:1570471792141125%43c11b7043c11b70"
}
...
--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q
Content-Type: application/http
Content-ID: response-
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
"name": "projects/35006771263/messages/0:1570471792141696%43c11b7043c11b70"
}
--batch_nDhMX4IzFTDLsCJ3kHH7v_44ua-aJT6q--
向主题发送消息
创建主题后,通过在客户端订阅客户端应用程序实例或通过服务器 API订阅主题,您可以向主题发送消息。如果这是您第一次为 FCM 构建发送请求,请参阅您的服务器环境和 FCM指南,了解重要的背景和设置信息。
在后端的发送逻辑中,指定所需的主题名称,如下所示:
节点.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);
Python
# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
topic=topic,
)
# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
去
// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Topic: topic,
}
// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
C#
// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Topic = topic,
};
// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
休息
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 -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
要向主题组合发送消息,请指定condition ,它是指定目标主题的布尔表达式。例如,以下条件会将消息发送到订阅了TopicA
和TopicB
或TopicC
的设备:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM 首先计算括号中的任何条件,然后从左到右计算表达式。在上面的表达式中,订阅任何单个主题的用户不会收到消息。同样,未订阅TopicA
的用户也不会收到消息。这些组合确实收到了它:
-
TopicA
和TopicB
-
TopicA
和TopicC
您最多可以在条件表达式中包含五个主题。
发送到一个条件:
节点.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);
Python
# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"
# See documentation on defining a message payload.
message = messaging.Message(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
condition=condition,
)
# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
去
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Condition: condition,
}
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
C#
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";
// See documentation on defining a message payload.
var message = new Message()
{
Notification = new Notification()
{
Title = "$GOOG up 1.43% on the day",
Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
},
Condition = condition,
};
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
休息
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 -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
发送一批消息
REST API 和 Admin SDK 支持批量发送消息。您可以将最多 500 条消息分组到一个批次中,并在单个 API 调用中将它们全部发送,与为每条消息发送单独的 HTTP 请求相比,性能显着提高。
此功能可用于构建一组自定义消息并将它们发送给不同的收件人,包括主题或特定设备注册令牌。例如,当您需要同时向消息正文中的详细信息略有不同的不同受众发送消息时,请使用此功能。
节点.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");
Python
# Create a list containing up to 500 messages.
messages = [
messaging.Message(
notification=messaging.Notification('Price drop', '5% off all electronics'),
token=registration_token,
),
# ...
messaging.Message(
notification=messaging.Notification('Price drop', '2% off all books'),
topic='readers-club',
),
]
response = messaging.send_all(messages)
# See the BatchResponse reference documentation
# for the contents of response.
print('{0} messages were sent successfully'.format(response.success_count))
去
// Create a list containing up to 500 messages.
messages := []*messaging.Message{
{
Notification: &messaging.Notification{
Title: "Price drop",
Body: "5% off all electronics",
},
Token: registrationToken,
},
{
Notification: &messaging.Notification{
Title: "Price drop",
Body: "2% off all books",
},
Topic: "readers-club",
},
}
br, err := client.SendAll(context.Background(), messages)
if err != nil {
log.Fatalln(err)
}
// See the BatchResponse reference documentation
// for the contents of response.
fmt.Printf("%d messages were sent successfully\n", br.SuccessCount)
C#
// Create a list containing up to 500 messages.
var messages = new List<Message>()
{
new Message()
{
Notification = new Notification()
{
Title = "Price drop",
Body = "5% off all electronics",
},
Token = registrationToken,
},
new Message()
{
Notification = new Notification()
{
Title = "Price drop",
Body = "2% off all books",
},
Topic = "readers-club",
},
};
var response = await FirebaseMessaging.DefaultInstance.SendAllAsync(messages);
// See the BatchResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");
休息
通过组合子请求列表构造 HTTP 批处理请求:
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"FCM Message",
"body":"This is an FCM notification message to device 0!"
}
}
}
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"topic":"readers-club",
"notification":{
"title":"Price drop",
"body":"2% off all books"
}
}
}
...
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /v1/projects/myproject-b5ae1/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"cR1rjyj4_Kc:APA91bGusqbypSuMdsh7jSNrW4nzsM...",
"notification":{
"title":"FCM Message",
"body":"This is an FCM notification message to device N!"
}
}
}
--subrequest_boundary--
您可以查询返回的BatchResponse
以检查有多少消息已成功传递给 FCM。它还公开了一个响应列表,可用于检查各个消息的状态。响应的顺序对应于输入列表中消息的顺序。
发送启用直接启动的消息(仅限 Android)
您可以使用 HTTP v1 或旧版 HTTP API 以直接启动模式向设备发送消息。在以直接启动模式发送到设备之前,请确保您已完成使客户端设备能够以直接启动模式接收 FCM 消息的步骤。
使用 FCM v1 HTTP API 发送
消息请求必须在请求正文的AndroidConfig
选项中包含键"direct_boot_ok" : true
。例如:
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,
},
}
使用 FCM 旧版 HTTP API 发送
消息请求必须在请求正文的顶层包含键"direct_boot_ok" : true
。例如:
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
"direct_boot_ok" : true
}
在请求正文中使用此密钥发送的消息可以由当前处于直接启动模式(以及不处于该模式时)的设备上的应用程序处理。
跨平台自定义消息
Firebase Admin SDK 和 FCM v1 HTTP 协议都允许您的消息请求设置message
对象中的所有可用字段。这包括:
- 一组通用字段,由接收消息的所有应用程序实例解释。
- 特定于平台的字段集,例如
AndroidConfig
和WebpushConfig
,仅由在指定平台上运行的应用程序实例解释。
特定于平台的块使您可以灵活地为不同平台自定义消息,以确保在收到消息时得到正确处理。 FCM 后端将考虑所有指定参数并为每个平台自定义消息。
何时使用公共字段
在以下情况下使用公共字段:
- 针对所有平台上的应用程序实例——Apple、Android 和 Web
- 向主题发送消息
所有应用程序实例,无论平台如何,都可以解释以下公共字段:
何时使用特定于平台的字段
当您需要时使用特定于平台的字段:
- 仅将字段发送到特定平台
- 除公共字段外,还发送特定于平台的字段
每当您只想将值发送到特定平台时,请不要使用公共字段;使用特定于平台的字段。例如,要仅向 Apple 平台和 Web 发送通知而不向 Android 发送通知,您必须使用两组不同的字段,一组用于 Apple,一组用于 Web。
当您发送具有特定传递选项的消息时,请使用特定于平台的字段来设置它们。如果需要,您可以为每个平台指定不同的值。然而,即使您想要跨平台设置基本相同的值,您也必须使用特定于平台的字段。这是因为每个平台对该值的解释可能略有不同——例如,生存时间在 Android 上设置为以秒为单位的过期时间,而在 Apple 上则设置为过期日期。
示例:带有颜色和图标选项的通知消息
此示例发送请求向所有平台发送通用通知标题和内容,但它也会向 Android 设备发送一些特定于平台的覆盖。
对于 Android,该请求设置了一个特殊的图标和颜色以显示在 Android 设备上。正如 AndroidNotification 的参考中所述,颜色以#rrggbb格式指定,图像必须是 Android 应用本地的可绘制图标资源。
这是用户设备上的视觉效果的近似值:
节点.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();
Python
message = messaging.Message(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
android=messaging.AndroidConfig(
ttl=datetime.timedelta(seconds=3600),
priority='normal',
notification=messaging.AndroidNotification(
icon='stock_ticker_update',
color='#f45342'
),
),
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
aps=messaging.Aps(badge=42),
),
),
topic='industry-tech',
)
去
oneHour := time.Duration(1) * time.Hour
badge := 42
message := &messaging.Message{
Notification: &messaging.Notification{
Title: "$GOOG up 1.43% on the day",
Body: "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
},
Android: &messaging.AndroidConfig{
TTL: &oneHour,
Notification: &messaging.AndroidNotification{
Icon: "stock_ticker_update",
Color: "#f45342",
},
},
APNS: &messaging.APNSConfig{
Payload: &messaging.APNSPayload{
Aps: &messaging.Aps{
Badge: &badge,
},
},
},
Topic: "industry-tech",
}
C#
var message = new Message
{
Notification = new Notification()
{
Title = "$GOOG up 1.43% on the day",
Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
},
Android = new AndroidConfig()
{
TimeToLive = TimeSpan.FromHours(1),
Notification = new AndroidNotification()
{
Icon = "stock_ticker_update",
Color = "#f45342",
},
},
Apns = new ApnsConfig()
{
Aps = new Aps()
{
Badge = 42,
},
},
Topic = "industry-tech",
};
休息
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 参考文档。
示例:带有自定义图像的通知消息
以下示例发送请求向所有平台发送一个通用的通知标题,但它也发送一个图像。这是用户设备上的视觉效果的近似值:
节点.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 参考文档。
示例:带有关联点击操作的通知消息
以下示例发送请求向所有平台发送一个通用的通知标题,但它也发送一个操作供应用程序执行以响应用户与通知的交互。这是用户设备上的视觉效果的近似值:
节点.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 参考文档。
示例:带有本地化选项的通知消息
以下示例发送请求为客户端发送本地化选项以显示本地化消息。这是用户设备上的视觉效果的近似值:
节点.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 参考文档。
管理员错误代码
下表列出了 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 | 提供的注册令牌未注册。先前有效的注册令牌可能因各种原因而被注销,包括:
|
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 Admin SDK 进行身份验证的文档,请参阅将 Firebase 添加到您的应用程序。 |
messaging/authentication-error | SDK 无法向 FCM 服务器进行身份验证。确保使用具有发送 FCM 消息的适当权限的凭据对 Firebase Admin SDK 进行身份验证。有关如何对 Firebase Admin SDK 进行身份验证的文档,请参阅将 Firebase 添加到您的应用程序。 |
messaging/server-unavailable | FCM 服务器无法及时处理请求。您应该重试相同的请求,但您必须:
|
messaging/internal-error | FCM 服务器在尝试处理请求时遇到错误。您可以按照上面messaging/server-unavailable 行中列出的要求重试相同的请求。如果错误仍然存在,请将问题报告给我们的错误报告支持渠道。 |
messaging/unknown-error | 返回了未知的服务器错误。有关详细信息,请参阅错误消息中的原始服务器响应。如果您收到此错误,请向我们的错误报告支持渠道报告完整的错误消息。 |
使用旧版应用服务器协议发送消息
如果您更喜欢使用旧版协议,请按本节所示构建消息请求。请记住,如果您通过 HTTP 向多个平台发送消息,v1 协议可以简化您的消息请求。
向特定设备发送消息
要向特定设备发送消息,请将to
键设置为特定应用程序实例的注册令牌。请参阅您的平台的客户端设置信息以了解有关注册令牌的更多信息。
HTTP POST 请求
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
HTTP响应
{ "multicast_id": 108, "success": 1, "failure": 0, "results": [ { "message_id": "1:08" } ] }
XMPP消息
<message id="">
<gcm xmlns="google:mobile:data">
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
</gcm>
</message>
XMPP 响应
<message id=""> <gcm xmlns="google:mobile:data"> { "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" } </gcm> </message>
XMPP 连接服务器提供了一些其他响应选项。请参阅服务器响应格式。
有关向客户端应用程序发送下游消息时可用消息选项的完整列表,请参阅您选择的连接服务器协议HTTP或XMPP的参考信息。
向主题发送消息
向 Firebase 云消息传递主题发送消息与向单个设备或用户组发送消息非常相似。应用服务器将to
键设置为/topics/yourTopic
类的值。开发者可以选择任何匹配正则表达式的主题名称: "/topics/[a-zA-Z0-9-_.~%]+"
。
要发送到多个主题的组合,应用服务器必须将condition
键(而不是to
键)设置为指定目标主题的布尔条件。例如,要向订阅了TopicA
和TopicB
或TopicC
的设备发送消息:
'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)
FCM 首先计算括号中的任何条件,然后从左到右计算表达式。在上面的表达式中,订阅任何单个主题的用户不会收到消息。同样,未订阅 TopicA 的用户也不会收到消息。这些组合确实收到了它:
- 主题A和主题B
- 话题A和话题C
您最多可以在条件表达式中包含五个主题,并且支持括号。支持的运营商: &&
, ||
.
主题 HTTP POST 请求
发送到单个主题:
https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
发送到订阅主题“狗”或“猫”的设备:
https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
主题 HTTP 响应
//Success example: { "message_id": "1023456" } //failure example: { "error": "TopicsMessageRateExceeded" }
主题 XMPP 消息
发送到单个主题:
<message id="">
<gcm xmlns="google:mobile:data">
</gcm>
</message>
发送到订阅主题“狗”或“猫”的设备:
<message id=""> <gcm xmlns="google:mobile:data"> </gcm> </message>
主题 XMPP 响应
//Success example: { "message_id": "1023456" } //failure example: { "error": "TopicsMessageRateExceeded" }
在 FCM 服务器返回对主题发送请求的成功或失败响应之前,预计会有长达 30 秒的延迟。确保相应地在请求中设置应用服务器的超时值。
向设备组发送消息
向设备组发送消息与向单个设备发送消息非常相似。将to
参数设置为设备组的唯一通知键。有关负载支持的详细信息,请参阅消息类型。本页中的示例展示了如何使用旧版 HTTP 和 XMPP 协议向设备组发送数据消息。
设备组 HTTP POST 请求
https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA { "to": "aUniqueKey", "data": { "hello": "This is a Firebase Cloud Messaging Device Group Message!", } }
设备组 HTTP 响应
下面是一个“成功”的例子notification_key
有 2 个与之关联的注册令牌,消息已成功发送给它们:
{ "success": 2, "failure": 0 }
这是“部分成功”的示例 — notification_key
有 3 个与之关联的注册令牌。消息仅成功发送到其中一个注册令牌。响应消息列出了未能收到消息的注册令牌 ( registration_ids
):
{ "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] }
当消息未能传递到与notification_key
关联的一个或多个注册令牌时,应用服务器应在重试之间进行退避重试。
如果服务器尝试向没有成员的设备组发送消息,则响应如下所示,0 次成功,0 次失败:
{ "success": 0, "failure": 0 }
设备组 XMPP 消息
<message id=""> <gcm xmlns="google:mobile:data"> { "to": "aUniqueKey", "message_id": "m-1366082849205" , "data": { "hello":"This is a Firebase Cloud Messaging Device Group Message!" } } </gcm> </message>
设备组 XMPP 响应
当消息成功发送到组中的任何一个设备时,XMPP 连接服务器以 ACK 响应。如果发送到组中所有设备的所有消息均失败,则 XMPP 连接服务器将以 NACK 进行响应。
下面是一个“成功”的例子notification_key
有 3 个与之关联的注册令牌,消息已成功发送给所有这些令牌:
{ "from": "aUniqueKey", "message_type": "ack", "success": 3, "failure": 0, "message_id": "m-1366082849205" }
这是“部分成功”的示例 — notification_key
有 3 个与之关联的注册令牌。消息仅成功发送到其中一个注册令牌。响应消息列出了未能接收消息的注册令牌:
{ "from": "aUniqueKey", "message_type": "ack", "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] }
当 FCM 连接服务器无法传送到组中的所有设备时。应用服务器将收到一个 nack 响应。
有关消息选项的完整列表,请参阅您选择的连接服务器协议HTTP或XMPP的参考信息。
Firebase Admin SDK 旧版发送方法
Firebase Admin Node.js SDK 支持基于旧版 FCM 服务器 API发送 (FCM) 消息的方法。与send()
方法相比,这些方法接受不同的参数。您应尽可能使用send()
方法,并且仅在向单个设备或设备组发送消息时使用本页中描述的方法。
发送到个人设备
您可以将注册令牌传递给sendToDevice()
方法以向该设备发送消息:
节点.js
// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';
// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the device corresponding to the provided
// registration token.
getMessaging().sendToDevice(registrationToken, payload)
.then((response) => {
// See the MessagingDevicesResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
sendToDevice()
方法还可以通过传递一组注册令牌而不是仅传递一个注册令牌来发送多播消息(即,向多个设备发送消息):
节点.js
// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...',
// ...
'ecupwIfBy1w:APA91bFtuMY7MktgxA3Au_Qx7cKqnf...'
];
// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the devices corresponding to the provided
// registration tokens.
getMessaging().sendToDevice(registrationTokens, payload)
.then((response) => {
// See the MessagingDevicesResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
sendToDevice()
方法返回一个由包含来自 FCM 的响应的MessagingDevicesResponse
对象解析的承诺。传递单个注册令牌或注册令牌数组时,返回类型具有相同的格式。
某些情况(例如身份验证错误或速率限制)会导致整个消息无法处理。在这些情况下,由sendToDevice()
返回的承诺会因错误而被拒绝。有关错误代码的完整列表,包括描述和解决步骤,请参阅管理 FCM API 错误。
发送到设备组
设备组消息传递允许您将多个设备添加到一个组中。这类似于主题消息传递,但包括身份验证以确保组成员资格仅由您的服务器管理。例如,如果你想向不同的手机型号发送不同的消息,你的服务器可以添加/删除对适当组的注册,并向每个组发送适当的消息。设备组消息传递不同于主题消息传递,因为它涉及从您的服务器而不是直接在您的应用程序中管理设备组。
您可以在应用服务器上通过旧版XMPP或HTTP协议使用设备组消息传递。用于 Node.js 的旧版 Firebase Admin SDK基于旧协议,还提供设备组消息传递功能。通知密钥允许的最大成员数为 20。
您可以通过应用服务器或 Android 客户端创建设备组并生成通知密钥。有关详细信息,请参阅管理设备组。
sendToDeviceGroup()
方法允许您通过指定设备组的通知密钥向该设备组发送消息:
节点.js
// See the "Managing device groups" link above on how to generate a
// notification key.
const notificationKey = 'some-notification-key';
// See the "Defining the message payload" section below for details
// on how to define a message payload.
const payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the device group corresponding to the provided
// notification key.
getMessaging().sendToDeviceGroup(notificationKey, payload)
.then((response) => {
// See the MessagingDeviceGroupResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
sendToDeviceGroup()
方法返回一个由包含来自 FCM 的响应的MessagingDevicesResponse
对象解析的承诺。
某些情况(例如身份验证错误或速率限制)会导致整个消息无法处理。在这些情况下,由sendToDeviceGroup()
返回的承诺会因错误而被拒绝。有关错误代码的完整列表,包括描述和解决步骤,请参阅管理 FCM API 错误。
定义消息负载
上述基于 FCM 遗留协议的方法接受消息有效负载作为它们的第二个参数,并支持通知和数据消息。您可以通过使用data
和/或notification
键创建对象来指定一种或两种消息类型。例如,这里是如何定义不同类型的消息负载:
通知消息
const payload = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
}
};
数据信息
const payload = {
data: {
score: '850',
time: '2:45'
}
};
组合讯息
const payload = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
data: {
stock: 'GOOG',
open: '829.62',
close: '635.67'
}
};
通知消息有效负载具有预定义的有效属性子集,并且根据您的目标移动操作系统而略有不同。有关完整列表,请参阅NotificationMessagePayload
的参考文档。
数据消息有效负载由具有一些限制的自定义键值对组成,包括所有值都必须是字符串这一事实。有关完整的限制列表,请参阅DataMessagePayload
的参考文档。
定义消息选项
上述基于 FCM 遗留协议的方法接受可选的第三个参数,指定消息的一些选项。例如,以下示例向 24 小时后过期的设备发送高优先级消息:
节点.js
// This registration token comes from the client FCM SDKs.
const registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';
// See the "Defining the message payload" section above for details
// on how to define a message payload.
const payload = {
notification: {
title: 'Urgent action needed!',
body: 'Urgent action is needed to prevent your account from being disabled!'
}
};
// Set the message as high priority and have it expire after 24 hours.
const options = {
priority: 'high',
timeToLive: 60 * 60 * 24
};
// Send a message to the device corresponding to the provided
// registration token with the provided options.
getMessaging().sendToDevice(registrationToken, payload, options)
.then((response) => {
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
有关可用选项的完整列表,请参阅MessagingOptions
的参考文档。