本頁面由 Cloud Translation API 翻譯而成。
Switch to English

構建應用服務器發送請求

使用Firebase Admin SDK或FCM應用服務器協議,您可以構建消息請求並將其發送到以下類型的目標:

  • 主題名稱
  • 健康)狀況
  • 設備註冊令牌
  • 設備組名稱(舊協議和僅適用於Node.js的Firebase Admin SDK)

您可以發送帶有由預定義字段組成的通知有效負載,您自己的用戶定義字段的數據有效負載或包含兩種有效負載類型的消息的消息。有關更多信息,請參見消息類型

此頁面中的示例顯示如何使用Firebase Admin SDK(具有對NodeJavaPythonC#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);

蟒蛇

# 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密鑰:

986

將消息發送到多個設備

REST API和Admin FCM API允許您將消息多播到設備註冊令牌列表。每次調用最多可以指定100個設備註冊令牌(Java和Node.js為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 100 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 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 100 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);
}

蟒蛇

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

蟒蛇

# 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以及TopicBTopicC設備發送消息:

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

FCM首先評估括號中的任何條件,然後從左到右評估表達式。在上面的表達式中,訂閱任何單個主題的用戶都不會收到該消息。同樣,未訂閱TopicA用戶也不會收到該消息。這些組合確實收到了它:

  • TopicATopicB
  • TopicATopicC

您的條件表達式中最多可以包含五個主題。

發送條件:

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

蟒蛇

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

蟒蛇

# 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 100 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_book_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_book_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_book_ok" : true
}

在請求主體中使用此鍵發送的消息可以由當前處於直接引導模式(以及不在該模式下)的設備上的應用處理。

跨平台自定義消息

在火力地堡管理SDK和FCM V1 HTTP協議都允許你的信息請求中設置的所有可用字段message的對象。這包括:

  • 接收消息的所有應用程序實例將解釋的一組通用字段。
  • 特定於平台的字段集,例如AndroidConfigWebpushConfig ,僅由在指定平台上運行的應用程序實例解釋。

特定於平台的塊使您可以靈活地為不同平台自定義消息,以確保在收到消息後正確處理它們。 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();

蟒蛇

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 提供的註冊令牌未註冊。出於多種原因,可以取消先前有效的註冊令牌,包括:
  • 客戶端應用已從FCM取消註冊。
  • 客戶端應用已自動註銷。如果用戶卸載了應用程序,或者在iOS上,如果APNs反饋服務將APNs令牌報告為無效,則可能會發生這種情況。
  • 註冊令牌已過期。例如,谷歌可能決定刷新註冊令牌,或者iOS設備的APNs令牌可能已過期。
  • 客戶端應用已更新,但新版本未配置為接收消息。
對於所有這些情況,請刪除此註冊令牌並停止使用它發送消息。
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服務器無法及時處理請求。您應該重試相同的請求,但是您必須:
  • 如果FCM Connection Server的響應中包含Retry-After標頭,請遵循該標頭。
  • 在重試機制中實現指數補償。例如,如果您在第一次重試之前等待了一秒鐘,則在下一次重試之前等待至少兩秒鐘,然後等待四秒鐘,依此類推。如果您要發送多封郵件,請為每封郵件單獨延遲一個額外的隨機量,以避免同時發出針對所有郵件的新請求。
導致問題的發件人可能會被列入黑名單。
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連接服務器提供了其他一些響應選項。請參閱服務器響應格式

有關將下游消息發送到客戶端應用程序時可用的消息選項的完整列表,請參閱所選連接服務器協議HTTPXMPP的參考信息。

向主題發送消息

將消息發送到Firebase Cloud Messaging主題與將消息發送到單個設備或用戶組非常相似。應用服務器將to鍵設置為/topics/yourTopic類的值。開發人員可以選擇與正則表達式匹配的任何主題名稱: "/topics/[a-zA-Z0-9-_.~%]+"

要發送到多個主題的組合,應用服務器必須將condition鍵(而不是to鍵)設置為指定目標主題的布爾條件。例如,要將消息發送到已訂閱TopicA以及TopicBTopicC

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

FCM首先評估括號中的任何條件,然後從左到右評估表達式。在上面的表達式中,訂閱任何單個主題的用戶都不會收到該消息。同樣,未訂閱TopicA的用戶也不會收到該消息。這些組合確實收到了它:

  • TopicA和TopicB
  • TopicA和TopicC

您的條件表達式中最多可以包含五個主題,並且支持括號。支持的運算符: &&||! 。注意的用法!

!('TopicA' in topics)

使用此表達式,所有未訂閱TopicA的應用程序實例(包括未訂閱任何主題的應用程序實例)都將收到此消息。

有關應用程序服務器密鑰的更多詳細信息,請參閱所選連接服務器協議HTTPXMPP的參考信息。此頁面中的示例顯示瞭如何將消息發送到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秒的延遲。確保在請求中相應設置應用服務器的超時值。

有關消息選項的完整列表,請參閱所選連接服務器協議HTTPXMPP的參考信息。

發送消息到設備組

將消息發送到設備組與將消息發送到單個設備非常相似。將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連接服務器無法傳送到組中的所有設備時。應用服務器將收到錯誤響應。

有關消息選項的完整列表,請參閱所選連接服務器協議HTTPXMPP的參考信息。

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錯誤

發送到設備組

設備組消息傳遞使您可以將多個設備添加到單個組。這類似於主題消息傳遞,但是包括身份驗證以確保僅由您的服務器管理組成員身份。例如,如果要將不同的消息發送到不同的手機型號,則服務器可以將註冊添加/刪除到適當的組,並將適當的消息發送到每個組。設備組消息傳遞與主題消息傳遞的不同之處在於,它涉及從服務器而不是直接在應用程序中管理設備組。

您可以通過應用服務器上的舊版XMPPHTTP協議使用設備組消息傳遞。基於舊協議的用於Node.jsFirebase 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的參考文檔。