Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

構建應用服務器發送請求

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

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

您可以使用由預定義字段組成的通知負載、您自己的用戶定義字段的數據負載或包含兩種類型負載的消息發送消息。見消息類型以獲取更多信息。

在這個頁面展示了如何使用火力地堡管理員SDK(其中有支持發送通知消息的實例節點Java的的PythonC#圍棋)和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。的火力地堡管理員SDK返回格式中的ID字符串projects/{project_id}/messages/{message_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 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

對於火力地堡管理員的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 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_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

將消息發送到主題的組合,指定一個條件,這是一個布爾表達式,指定目標的主題。例如,下面的條件將郵件發送到訂閱了設備TopicA並且或者TopicBTopicC

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

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

  • TopicATopicB
  • TopicATopicC

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

發送到條件:

節點.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 和管理 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 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 發送

該消息請求必須包括關鍵"direct_boot_ok" : trueAndroidConfig請求主體的選項。例如:

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的對象。這包括:

  • 字段的一組公共到由接收該消息的所有的應用程序實例進行解釋。
  • 領域,如平台的特定集合AndroidConfigWebpushConfig ,由指定的平台上運行的應用情況下,僅解釋。

特定於平台的塊使您可以靈活地為不同平台定制消息,以確保在接收時正確處理它們。 FCM 後端將考慮所有指定的參數並為每個平台定制消息。

何時使用公共字段

在以下情況下使用通用字段:

  • 所有平台上指定的應用程式實例-的iOS,Android和網絡
  • 向主題發送消息

所有應用程序實例,無論平台如何,都可以解釋以下常見字段:

何時使用特定於平台的字段

當您想要執行以下操作時,請使用特定於平台的字段:

  • 僅將字段發送到特定平台
  • 發送平台的具體領域,除了常見的領域

每當你想發送值只對特定的平台,不要使用常見的領域;使用特定於平台的字段。例如,要僅向 iOS 和 Web 發送通知而不向 Android 發送通知,您必須使用兩組單獨的字段,一組用於 iOS,一組用於 Web。

當您發送特定消息的傳遞選項,使用特定於平台的字段設置。如果需要,您可以為每個平台指定不同的值。但是,即使您希望跨平台設置基本相同的值,您也必須使用特定於平台的字段。這是因為每個平台可以解釋略有不同,例如,時間到現場設置在Android上以秒到期時間的價值,而iOS上它被設置為截止日期

示例:帶有顏色和圖標選項的通知消息

此示例發送請求向所有平台發送通用通知標題和內容,但它也向 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提供的註冊令牌未註冊。以前有效的註冊令牌可能因多種原因被取消註冊,包括:
  • 客戶端應用程序從 FCM 註銷了自己。
  • 客戶端應用程序已自動註銷。如果用戶卸載應用程序,或者在 iOS 上,如果 APNs 反饋服務報告 APNs 令牌無效,就會發生這種情況。
  • 註冊令牌已過期。例如,Google 可能決定刷新註冊令牌,或者 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 項目。見添加火力地堡到您的應用程序,了解如何在火力地堡管理的SDK驗證文檔。
messaging/authentication-error SDK 無法向 FCM 服務器進行身份驗證。確保您使用具有發送 FCM 消息的適當權限的憑據對 Firebase Admin SDK 進行身份驗證。見添加火力地堡到您的應用程序,了解如何在火力地堡管理的SDK驗證文檔。
messaging/server-unavailable FCM 服務器無法及時處理請求。您應該重試相同的請求,但您必須:
  • 榮譽Retry-After報頭,如果它被包括在從FCM連接服務器的響應。
  • 在您的重試機制中實現指數退避。例如,如果您在第一次重試前等待了 1 秒鐘,則在下一次重試前至少等待 2 秒鐘,然後是 4 秒鐘,依此類推。如果您要發送多條消息,請將每條消息單獨延遲一個額外的隨機量,以避免同時對所有消息發出新請求。
導致問題的發件人有被列入黑名單的風險。
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 雲消息傳遞主題發送消息與向單個設備或用戶組發送消息非常相似。該應用程序服務器將to使用的值等關鍵/topics/yourTopic 。開發人員可以選擇與正則表達式匹配任何主題的名稱: "/topics/[a-zA-Z0-9-_.~%]+"

要發送到的多個主題組合,應用程序服務器必須設置condition鍵(而不是to鍵)一個布爾條件,其指定目標的主題。例如,將消息發送到訂閱了設備TopicA並且或者TopicBTopicC

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

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

  • 主題A和主題B
  • TopicA 和 TopicC

您最多可以在條件表達式中包含五個主題,並且支持括號。支持的運營商: &&|| .

主題 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註冊標記與它相關聯。該消息僅成功發送到 1 個註冊令牌。該響應消息列表中的註冊標記( 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註冊標記與它相關聯。該消息僅成功發送到 1 個註冊令牌。響應消息列出了未能接收到消息的註冊令牌:

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

當 FCM 連接服務器下發到組內所有設備失敗時。應用服務器將收到一個 nack 響應。

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

Firebase Admin SDK 舊版發送方法

在火力地堡管理Node.js的SDK支持發送基於(FCM)消息的方法傳統FCM服務器API 。相比這些方法都接受不同的參數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()方法返回與一個解決一個承諾MessagingDevicesResponse含有來自FCM響應對象。傳遞單個註冊令牌或註冊令牌數組時,返回類型具有相同的格式。

某些情況(例如身份驗證錯誤或速率限制)會導致整個消息無法處理。在這些情況下,許返回的sendToDevice()被拒絕,並出現錯誤。有關錯誤代碼,包括說明和解決步驟的完整列表,請參閱管理員FCM API錯誤

發送到設備組

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

您可以通過使用傳統設備組消息XMPPHTTP協議,你的應用服務器上。火力地堡管理SDK用於Node.js的基礎上,傳統協議還提供設備群發功能。通知鍵允許的最大成員數為 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()方法返回與一個解決一個承諾MessagingDeviceGroupResponse含有來自FCM響應對象。

某些情況(例如身份驗證錯誤或速率限制)會導致整個消息無法處理。在這些情況下,許返回的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可用選項的完整列表。