使用Firebase Admin SDK或FCM應用服務器協議,您可以構建消息請求並將其發送到以下類型的目標:
- 主題名稱
- 狀況
- 設備註冊令牌
- 設備組名稱(舊協議和僅適用於Node.js的Firebase Admin SDK)
您可以發送包含由預定義字段組成的通知有效負載,您自己的用戶定義字段的數據有效負載或包含兩種有效負載類型的消息的消息。有關更多信息,請參見消息類型。
本頁中的示例顯示瞭如何使用Firebase Admin SDK(具有對Node , Java , Python , C#和Go的支持)和v1 HTTP協議發送通知消息。還提供了有關通過舊版HTTP和XMPP協議發送消息的指南。
將消息發送到特定設備
要發送到單個特定設備,請如圖所示傳遞設備的註冊令牌。請參閱您所用平台的客戶端設置信息,以了解有關註冊令牌的更多信息。
Node.js
// This registration token comes from the client FCM SDKs.
var registrationToken = 'YOUR_REGISTRATION_TOKEN';
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().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命令:
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方法都會返回一條消息ID。 Firebase Admin SDK返回ID字符串,格式為projects/{project_id}/messages/{message_id}
。 HTTP協議響應是單個JSON密鑰:
{
"name":"projects/myproject-b5ae1/messages/0:1500415314455276%31bd1c9631bd1c96"
}
將消息發送到多個設備
REST API和Admin FCM API允許您將消息多播到設備註冊令牌列表。每次調用最多可以指定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,
}
admin.messaging().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 100 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
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
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
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
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"' https://fcm.googleapis.com/batch
對於Firebase Admin SDK,此操作在sendAll()
使用sendAll()
API,如示例所示。返回值是BatchResponse
其響應列表與輸入令牌的順序相對應。當您要檢查哪些令牌導致錯誤時,此功能很有用。
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,
}
admin.messaging().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 100 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_
。
--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指南以獲取重要的背景和設置信息。
在後端的發送邏輯中,指定所需的主題名稱,如下所示:
Node.js
// The topic name can be optionally prefixed with "/topics/".
var topic = 'highScores';
var message = {
data: {
score: '850',
time: '2:45'
},
topic: topic
};
// Send a message to devices subscribed to the provided topic.
admin.messaging().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命令:
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
您的條件表達式中最多可以包含五個主題。
發送條件:
Node.js
// 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 = {
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.
admin.messaging().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命令:
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請求相比,性能有了顯著提高。
此功能可用於構建一組自定義的消息,並將其發送給不同的收件人,包括主題或特定的設備註冊令牌。例如,當您需要同時將消息正文中的詳細信息稍有不同的消息發送給不同的受眾時,請使用此功能。
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',
});
admin.messaging().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 100 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
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
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
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
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
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
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
}
在請求主體中使用此鍵發送的消息可以由當前處於直接引導模式(以及不在該模式下)的設備上的應用處理。
跨平台自定義消息
在火力地堡管理SDK和FCM V1 HTTP協議都允許你的信息請求中設置的所有可用字段message
的對象。這包括:
- 接收消息的所有應用程序實例將解釋的一組通用字段。
- 特定於平台的字段集,例如
AndroidConfig
和WebpushConfig
,僅由在指定平台上運行的應用程序實例解釋。
特定於平台的塊使您可以靈活地針對不同平台自定義消息,以確保在收到消息後正確處理它們。 FCM後端將考慮所有指定的參數,並為每個平台自定義消息。
何時使用通用字段
在以下情況下,請使用常見字段:
- 在所有平台(iOS,Android和Web)上定位應用程序實例
- 向主題發送消息
無論平台如何,所有應用程序實例都可以解釋以下公共字段:
何時使用特定於平台的字段
當您要執行以下操作時,請使用特定於平台的字段:
- 僅將字段發送到特定平台
- 除常見字段外,還發送特定於平台的字段
每當您只想將值發送到特定平台時,都不要使用公共字段。使用特定於平台的字段。例如,要僅向iOS和Web發送通知,而不向Android發送通知,則必須使用兩組單獨的字段,一組用於iOS,另一組用於Web。
當您發送帶有特定傳遞選項的郵件時,請使用特定於平台的字段進行設置。如果需要,可以為每個平台指定不同的值。但是,即使您想在各個平台上設置基本相同的值,也必須使用特定於平台的字段。這是因為每個平台對值的解釋都略有不同-例如,將生存時間在Android上設置為以秒為單位的到期時間,而在iOS上將其設置為到期日期。
示例:帶有顏色和圖標選項的通知消息
此示例發送請求向所有平台發送了通用的通知標題和內容,但同時也向Android設備發送了特定於平台的替代內容。
對於Android,該請求會設置一個特殊的圖標和顏色,以顯示在Android設備上。如AndroidNotification的參考中所述,顏色以#rrggbb格式指定,並且圖像必須是Android應用本地的可繪製圖標資源。
這是用戶設備上視覺效果的近似值:
Node.js
var admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
var topicName = 'industry-tech'
var 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,
};
admin.messaging().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參考文檔。
示例:帶有自定義圖像的通知消息
以下示例發送請求將通用通知標題發送到所有平台,但它還會發送圖像。這是用戶設備上視覺效果的近似值:
Node.js
var admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
var topicName = 'industry-tech'
var message = {
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''
}
},
topic: topicName,
};
admin.messaging().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
var admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
var topicName = 'industry-tech'
var message = {
notification: {
title: 'Breaking News....'
},
android: {
notification: {
click_action: 'news_intent'
}
},
apns: {
payload: {
aps: {
'category': 'INVITE_CATEGORY'
}
}
},
webpush: {
fcm_options: {
link: 'breakingnews.html'
}
},
topic: topicName,
};
admin.messaging().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 admin = require("firebase-admin")
admin.initializeApp({
credential: admin.credential.applicationDefault(),
});
var topicName = 'industry-tech'
var message = {
android: {
ttl: 3600000,
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']
}
}
}
},
topic: topicName,
};
admin.messaging().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 | 無法發送針對iOS設備的消息,因為所需的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 Cloud Messaging主題與將消息發送到單個設備或用戶組非常相似。應用服務器將to
key設置為/topics/yourTopic
類的值。開發人員可以選擇與正則表達式匹配的任何主題名稱: "/topics/[a-zA-Z0-9-_.~%]+"
。
要發送到多個主題的組合,應用服務器必須將condition
鍵(而不是to
鍵)設置為指定目標主題的布爾條件。例如,要將消息發送到已訂閱TopicA
以及TopicB
或TopicC
:
'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)
FCM首先評估括號中的任何條件,然後從左到右評估表達式。在上面的表達式中,訂閱任何單個主題的用戶都不會收到該消息。同樣,未訂閱TopicA的用戶也不會收到該消息。這些組合確實收到了它:
- TopicA和TopicB
- TopicA和TopicC
您的條件表達式中最多可以包含五個主題,並且支持括號。支持的運算符: &&
, ||
。
有關應用程序服務器密鑰的更多詳細信息,請參閱所選連接服務器協議HTTP或XMPP的參考信息。本頁中的示例顯示瞭如何將消息發送到HTTP和XMPP中的主題。
主題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秒的延遲。確保在請求中相應設置應用服務器的超時值。
有關消息選項的完整列表,請參閱所選連接服務器協議HTTP或XMPP的參考信息。
發送消息到設備組
將消息發送到設備組與將消息發送到單個設備非常相似。將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個與之關聯的註冊令牌。該消息僅成功發送到1個註冊令牌。響應消息列出了未能接收到該消息的註冊令牌:
{ "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個與之關聯的註冊令牌。該消息僅成功發送到1個註冊令牌。響應消息列出了未能接收到該消息的註冊令牌:
{ "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()
方法,以向該設備發送消息:
Node.js
// This registration token comes from the client FCM SDKs.
var registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';
// See the "Defining the message payload" section below for details
// on how to define a message payload.
var payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().sendToDevice(registrationToken, payload)
.then(function(response) {
// See the MessagingDevicesResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
sendToDevice()
方法還可以通過傳遞註冊令牌數組而不是單個註冊令牌來發送多播消息(即,將消息發送到多個設備):
Node.js
// These registration tokens come from the client FCM SDKs.
var registrationTokens = [
'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...',
// ...
'ecupwIfBy1w:APA91bFtuMY7MktgxA3Au_Qx7cKqnf...'
];
// See the "Defining the message payload" section below for details
// on how to define a message payload.
var payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the devices corresponding to the provided
// registration tokens.
admin.messaging().sendToDevice(registrationTokens, payload)
.then(function(response) {
// See the MessagingDevicesResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
sendToDevice()
方法返回一個承諾,該承諾將通過包含FCM響應的MessagingDevicesResponse
對象進行解析。傳遞單個註冊令牌或註冊令牌數組時,返回類型具有相同的格式。
某些情況(例如,身份驗證錯誤或速率限制)會導致整個消息無法處理。在這些情況下, sendToDevice()
返回的promise將被拒絕並顯示錯誤。有關錯誤代碼的完整列表,包括描述和解決步驟,請參閱Admin FCM API錯誤。
發送到設備組
設備組消息傳遞使您可以將多個設備添加到單個組中。這類似於主題消息傳遞,但是包括身份驗證以確保僅由您的服務器管理組成員身份。例如,如果要將不同的消息發送到不同的手機型號,則服務器可以將註冊添加/刪除到適當的組,並將適當的消息發送到每個組。設備組消息傳遞與主題消息傳遞的不同之處在於,它涉及從服務器而非直接在應用程序內部管理設備組。
您可以通過應用服務器上的舊版XMPP或HTTP協議使用設備組消息傳遞。基於舊版協議的用於Node.js的Firebase Admin SDK還提供了設備組消息傳遞功能。通知密鑰允許的最大成員數量為20。
您可以通過應用服務器或Android客戶端創建設備組並生成通知密鑰。有關詳細信息,請參見管理設備組。
sendToDeviceGroup()
方法允許您通過為設備組指定通知鍵來向該設備組發送消息:
Node.js
// See the "Managing device groups" link above on how to generate a
// notification key.
var notificationKey = 'some-notification-key';
// See the "Defining the message payload" section below for details
// on how to define a message payload.
var payload = {
data: {
score: '850',
time: '2:45'
}
};
// Send a message to the device group corresponding to the provided
// notification key.
admin.messaging().sendToDeviceGroup(notificationKey, payload)
.then(function(response) {
// See the MessagingDeviceGroupResponse reference documentation for
// the contents of response.
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
sendToDeviceGroup()
方法返回一個承諾,該承諾可以通過包含FCM響應的MessagingDeviceGroupResponse
對象進行解析。
某些情況(例如,身份驗證錯誤或速率限制)會導致整個消息無法處理。在這些情況下, sendToDeviceGroup()
返回的promise將被拒絕並顯示錯誤。有關錯誤代碼的完整列表,包括描述和解決步驟,請參閱Admin FCM API錯誤。
定義消息有效負載
基於FCM傳統協議的上述方法接受消息有效負載作為其第二個參數,並支持通知消息和數據消息。您可以通過使用data
和/或notification
鍵創建一個對象來指定一種或兩種消息類型。例如,以下是定義不同類型的消息有效負載的方法:
通知訊息
var 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.'
}
};
數據信息
var payload = {
data: {
score: '850',
time: '2:45'
}
};
合併訊息
var 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小時後過期:
Node.js
// This registration token comes from the client FCM SDKs.
var registrationToken = 'bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...';
// See the "Defining the message payload" section above for details
// on how to define a message payload.
var 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.
var options = {
priority: 'high',
timeToLive: 60 * 60 * 24
};
// Send a message to the device corresponding to the provided
// registration token with the provided options.
admin.messaging().sendToDevice(registrationToken, payload, options)
.then(function(response) {
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
有關可用選項的完整列表,請參閱MessagingOptions
的參考文檔。