Firebase Cloud Messaging的服務器端包含兩個組件:
- Google提供的FCM後端。
- 您的應用服務器或運行服務器邏輯的其他受信任服務器環境,例如Firebase的雲功能或Google管理的其他雲環境。
您的應用服務器或受信任服務器環境將消息請求發送到FCM後端,然後FCM後端將消息路由到在用戶設備上運行的客戶端應用。
可信服務器環境的要求
您的應用服務器環境必須滿足以下條件:
- 能夠將格式正確的消息請求發送到FCM後端。
- 能夠處理請求並使用指數補償重新發送它們。
- 能夠安全地存儲服務器授權憑證和客戶端註冊令牌。
- 對於XMPP協議(如果使用),服務器必須能夠生成消息ID以唯一地標識其發送的每條消息(FCM HTTP後端生成消息ID並在響應中返回它們)。每個發件人ID,XMPP消息ID均應唯一。
選擇服務器選項
您需要確定一種與FCM服務器交互的方式:使用Firebase Admin SDK或原始協議。由於Firebase Admin SDK對流行的編程語言的支持以及用於處理身份驗證和授權的便捷方法,因此推薦使用Firebase Admin SDK。
與FCM服務器交互的選項包括:- Firebase Admin SDK,具有對Node , Java , Python , C#和Go的支持。
- FCM HTTP v1 API是最新的協議選項,具有更安全的授權和靈活的跨平台消息傳遞功能(Firebase Admin SDK基於此協議並提供其所有固有優勢)。
- 舊版HTTP協議。
- XMPP服務器協議。請注意,如果要使用客戶端應用程序中的上游消息傳遞,則必須使用XMPP。
用於FCM的Firebase Admin SDK
Admin FCM API處理與後端的身份驗證,並有助於發送消息和管理主題訂閱。使用Firebase Admin SDK,您可以:
- 將消息發送到單個設備
- 將消息發送到與一個或多個主題匹配的主題和條件語句。
- 在主題之間訂閱和退訂設備
- 構建適合於不同目標平台的消息有效負載
Admin Node.js SDK提供了將消息發送到設備組的方法。
要設置Firebase Admin SDK,請參閱將Firebase Admin SDK添加到您的服務器。如果您已經有Firebase項目,請從添加SDK開始。然後,一旦安裝了Firebase Admin SDK,您就可以開始編寫邏輯以構建發送請求。
FCM服務器協議
當前,FCM提供以下原始服務器協議:
您的應用服務器可以單獨或串聯使用這些協議。由於它是向多個平台發送消息的最新,最靈活的方法,因此建議在可行的情況下使用FCM HTTP v1 API。如果您的要求包括從設備到服務器的上游消息傳遞,則需要實現XMPP協議。
XMPP消息傳遞與HTTP消息傳遞在以下方面有所不同:
- 上游/下游消息
- HTTP:僅下游,雲到設備。
- XMPP:上游和下游(設備到雲,雲到設備)。
- 消息傳遞(同步或異步)
- HTTP:同步。應用服務器將消息作為HTTP POST請求發送,並等待響應。此機制是同步的,阻止發送方發送另一條消息,直到收到響應為止。
- XMPP:異步的。應用服務器通過持久XMPP連接以全線速向所有設備發送消息/從所有設備接收消息。 XMPP連接服務器異步發送確認或失敗通知(以特殊ACK和NACK JSON編碼的XMPP消息的形式)。
- JSON格式
- HTTP:作為HTTP POST發送的JSON消息。
- XMPP:封裝在XMPP消息中的JSON消息。
- 純文本
- HTTP:以HTTP POST發送的純文本消息。
- XMPP:不支持。
- 下游組播發送到多個註冊令牌。
- HTTP:以JSON消息格式支持。
- XMPP:不支持。
實施HTTP服務器協議
為了發送消息,應用服務器發出帶有HTTP標頭和由JSON鍵值對組成的HTTP正文的POST請求。有關標題和正文選項的詳細信息,請參閱構建App Server發送請求。
實施XMPP服務器協議
FCM消息的JSON有效負載類似於HTTP協議,但以下情況除外:
- 不支持多個收件人。
- FCM添加了必填字段
message_id
。此ID唯一標識XMPP連接中的消息。來自FCM的ACK或NACK使用message_id
標識從應用程序服務器發送到FCM的消息。因此,重要的是,此message_id
不僅要唯一(每個發件人ID ),而且要始終存在。 - XMPP使用服務器密鑰授權與FCM的持久連接。有關更多信息,請參見授權發送請求。
除了常規FCM消息外,還發送控制消息,由JSON對像中的message_type
字段指示。該值可以是“ ack”或“ nack”或“ control”(請參見下面的格式)。服務器可以忽略任何帶有未知message_type
FCM消息。
對於您的應用服務器從FCM收到的每條設備消息,它都需要發送一個ACK消息。它永遠不需要發送NACK消息。如果您不發送消息的ACK,則FCM將在下次建立新的XMPP連接時重新發送該消息,除非該消息首先過期。
FCM還為每個服務器到設備消息發送一個ACK或NACK。如果您沒有收到任何消息,則表明在操作過程中TCP連接已關閉,並且服務器需要重新發送消息。有關詳細信息,請參見流控制。
有關所有消息參數的列表,請參見協議參考。
要求格式
帶有有效負載的消息—通知消息
這是通知消息的XMPP節:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "notification": { "title": "Portugal vs. Denmark”, "body”: "5 to 1” }, "time_to_live":"600" } } </gcm> </message>
帶有效載荷的消息—數據消息
這是一個XMPP節,其中包含從應用程序服務器到FCM的JSON消息:
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "message_id":"m-1366082849205" // new required field "data": { "hello":"world", } "time_to_live":"600", } </gcm> </message>
回應格式
FCM響應可以具有三種可能的形式。第一個是常規的“ ack”消息。但是,當響應包含錯誤時,消息可以採用兩種不同的形式,如下所述。
確認消息
這是一個XMPP節,其中包含從FCM到應用程序服務器的ACK / NACK消息:
<message id=""> <gcm xmlns="google:mobile:data"> { "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" } </gcm> </message>
NACK消息
NACK錯誤是常規XMPP消息,其中message_type
狀態消息為“ nack”。 NACK消息包含:
- NACK錯誤代碼。
- NACK錯誤描述。
以下是一些示例。
錯誤的註冊:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"SomeInvalidRegistrationId", "error":"BAD_REGISTRATION", "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId" } </gcm> </message>
無效的JSON:
<message> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "error":"INVALID_JSON", "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc" } </gcm> </message>
超過設備消息速率:
<message id="..."> <gcm xmlns="google:mobile:data"> { "message_type":"nack", "message_id":"msgId1", "from":"REGID", "error":"DEVICE_MESSAGE_RATE_EXCEEDED", "error_description":"Downstream message rate exceeded for this registration id" } </gcm> </message>
有關NACK錯誤代碼的完整列表,請參見服務器參考。除非另有說明,否則不應重試NACKed消息。意外的NACK錯誤代碼應與INTERNAL_SERVER_ERROR
相同。
節錯誤
在某些情況下,您還可能會遇到一個節錯誤。節錯誤包含:
- 節錯誤代碼。
- 節錯誤描述(自由文本)。
例如:
<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC"> <gcm xmlns="google:mobile:data"> {"random": "text"} </gcm> <error code="400" type="modify"> <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"> InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n </text> </error> </message>
控制訊息
FCM需要定期關閉連接以執行負載平衡。在關閉連接之前,FCM發送CONNECTION_DRAINING
消息以指示連接正在耗盡,即將關閉。 “排空”是指關閉進入連接的消息流,但允許管道中已有的任何內容繼續進行。當您收到CONNECTION_DRAINING
消息時,應立即開始將消息發送到另一個FCM連接,並在必要時打開一個新連接。但是,您應該保持原始連接的打開狀態,並繼續接收可能通過該連接發出的消息(並對其進行確認)-FCM準備就緒時將關閉連接。
CONNECTION_DRAINING
消息如下所示:
<message> <data:gcm xmlns:data="google:mobile:data"> { "message_type":"control" "control_type":"CONNECTION_DRAINING" } </data:gcm> </message>
CONNECTION_DRAINING
是當前唯一支持的control_type
。
流量控制
發送到FCM的每個消息都會收到ACK或NACK響應。尚未收到這些響應之一的郵件將被視為待處理。如果待處理消息數達到100,則應用服務器應停止發送新消息,並等待FCM確認一些現有的待處理消息,如圖1所示:

圖1.消息/確認流程。
相反,為避免使應用服務器過載,如果有太多未確認的消息,FCM將停止發送。因此,應用服務器應盡快“確認”通過FCM從客戶端應用收到的上游消息,以保持傳入消息的恆定流。前述未決消息限制不適用於這些ACK。即使未決消息計數達到100,應用服務器也應繼續發送針對從FCM接收到的消息的ACK,以避免阻止新的上游消息的傳遞。
ACK僅在一個連接的上下文中有效。如果在確認消息之前關閉了連接,則應用服務器應等待FCM重新發送上游消息,然後再次確認。同樣,應重新發送在關閉連接之前未從FCM收到ACK / NACK的所有待處理消息。