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

您的服務器環境和FCM

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,具有對NodeJavaPythonC#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的所有待處理消息。