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

關於 FCM 消息

Firebase 雲消息傳遞 (FCM) 提供了廣泛的消息傳遞選項和功能。此頁面中的信息旨在幫助您了解不同類型的 FCM 消息以及您可以使用它們做什麼。

消息類型

使用 FCM,您可以向客戶端發送兩種類型的消息:

  • 通知消息,有時被認為是“顯示消息”。這些由 FCM SDK 自動處理。
  • 數據消息,由客戶端應用程序處理。

通知消息包含一組預定義的用戶可見鍵。相比之下,數據消息僅包含用戶定義的自定義鍵值對。通知消息可以包含可選的數據負載。兩種消息類型的最大有效負載均為 4000 字節,但從 Firebase 控制台發送消息時除外,該控制台強制執行 1024 個字符限制。

使用場景如何發送
通知訊息FCM 代表客戶端應用程序自動向最終用戶設備顯示消息。通知消息具有一組預定義的用戶可見鍵和自定義鍵值對的可選數據負載。
  1. 在可信環境,例如雲功能或你的應用服務器,使用管理SDKFCM服務器協議:設置notification的關鍵。可能有可選的數據負載。始終可折疊。

    看到一些顯示通知的例子和發送請求的有效載荷。

  2. 使用通知作曲:輸入郵件正文,標題等,並發送。通過提供自定義數據來添加可選的數據負載。
數據信息客戶端應用程序負責處理數據消息。數據消息只有自定義鍵值對,沒有保留鍵名(見下文)。在可信環境,例如雲功能或你的應用服務器,使用管理SDKFCM服務器協議:將data唯一的關鍵。

當您希望 FCM 代表您的客戶端應用程序處理顯示通知時,請使用通知消息。當您想要在客戶端應用程序上處理消息時,請使用數據消息。

FCM 可以發送包含可選數據負載的通知消息。在這種情況下,FCM 處理顯示通知負載,而客戶端應用程序處理數據負載。

通知消息

為了測試或進行營銷和用戶重新接合,你可以發送郵件使用火力地堡控制台通知消息。在火力地堡控制台提供基於分析的A / B測試,以細化的幫助和提高營銷信息。

到使用管理SDK或FCM協議編程方式發送通知消息,設置notification必要的預定義集合的用於通知消息的用戶可見部分鍵值選擇鍵。例如,這是一個 IM 應用程序中的 JSON 格式的通知消息。用戶可能會看到標題為“葡萄牙 vs. 丹麥”和文本“非常匹配!”的消息。在設備上:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
  }
}

當應用程序在後台時,通知消息會傳送到通知托盤。對於前台的應用程序,消息由回調函數處理。

有關可用於構建通知消息的預定義鍵的完整列表,請參閱參考文檔:

數據信息

使用您的自定義鍵值對設置適當的鍵,以將數據負載發送到客戶端應用程序。

例如,這裡是在相同的IM應用程序的JSON格式消息如上,其中所述信息被封裝在公共data密鑰和客戶端應用程序預期解釋內容:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "data":{
      "Nick" : "Mario",
      "body" : "great match!",
      "Room" : "PortugalVSDenmark"
    }
  }
}

頂層,或共同的上述例子中示出了使用data字段,其由客戶端解釋上接收所述消息的所有平台。在每個平台上,客戶端應用程序在回調函數中接收數據負載。

數據消息加密

Android的傳輸層(見FCM架構)使用點至點加密。根據您的需要,您可以決定向數據消息添加端到端加密。 FCM 不提供端到端的解決方案。不過,也有可用的外部解決方案,如毛細管DTLS

帶有可選數據負載的通知消息

以編程方式或通過 Firebase 控制台,您可以發送包含自定義鍵值對可選負載的通知消息。在通知作曲家,使用高級選項自定義數據字段。

接收同時包含通知和數據有效載荷的消息時的應用行為取決於應用是在後台還是在前台——本質上,它在接收時是否處於活動狀態。

  • 時在後台,應用接收在通知托盤中的通知有效載荷,並且當用戶點按通知僅處理所述數據有效負載。
  • 當在前台,您的應用程序與接收都可用有效載荷的消息對象。

下面是同時含有的JSON格式消息notification密鑰和data項:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    },
    "data" : {
      "Nick" : "Mario",
      "Room" : "PortugalVSDenmark"
    }
  }
}

跨平台自定義消息

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

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

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

何時使用公共字段

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

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

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

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

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

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

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

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

示例:具有特定於平台的傳遞選項的通知消息

以下 v1 發送請求向所有平台發送通用通知標題和內容,但也發送一些特定於平台的覆蓋。具體來說,請求:

  • 為 Android 和 Web 平台設置較長的生存時間,同時將 APNs (iOS) 消息優先級設置為低設置
  • 設置適當的鍵來對Android和iOS通知用戶抽頭的結果- click_action ,和category分別。
{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"Match update",
       "body":"Arsenal goal in added time, score is now 3-0"
     },
     "android":{
       "ttl":"86400s",
       "notification"{
         "click_action":"OPEN_ACTIVITY_1"
       }
     },
     "apns": {
       "headers": {
         "apns-priority": "5",
       },
       "payload": {
         "aps": {
           "category": "NEW_MESSAGE_CATEGORY"
         }
       }
     },
     "webpush":{
       "headers":{
         "TTL":"86400"
       }
     }
   }
 }

看到HTTP V1參考文檔關於在消息主體中的平台特定塊中可用的密鑰完整細節。有關構建包含郵件正文,請參閱發送請求的詳細信息生成發送請求

交付選項

FCM 為發送到 Android 設備的消息提供了一組特定的傳遞選項,並允許在 iOS 和 Web 上使用類似的選項。例如,“可折疊”消息的行為是通過FCM的支持在Android collapse_key通過,在iOS apns-collapse-id ,並通過JavaScript / Web上的Topic 。具體請參見本節的描述和相關參考文檔。

不可折疊和可折疊的消息

非可折疊消息表明每個單獨的消息被傳遞到該裝置。不可折疊的消息提供一些有用的內容,而不是可折疊的消息,例如向移動應用程序發送無內容“ping”以聯繫服務器以獲取數據。

不可折疊消息的一些典型用例是聊天消息或關鍵消息。例如,在 IM 應用程序中,您可能希望發送每條消息,因為每條消息都有不同的內容。

對於 Android,有 100 條消息的限制,可以在不折疊的情況下存儲。如果達到限制,則丟棄所有存儲的消息。當設備重新聯機時,它會收到一條特殊消息,指示已達到限制。然後應用程序可以正確處理這種情況,通常是通過從應用程序服務器請求完全同步。

一種可折疊的消息是可以由一個新的消息被替換,如果它尚未被傳遞到設備的消息。

可折疊消息的一個常見用例是用於告訴移動應用程序從服務器同步數據的消息。一個例子是一個體育應用程序,它用最新的分數更新用戶。只有最近的消息是相關的。

到消息標記為可折疊在Android,包括collapse_key在消息的有效載荷的參數。默認情況下,折疊鍵是在 Firebase 控制台中註冊的應用程序包名稱。 FCM 服務器可以同時為每個設備存儲四個不同的可折疊消息,每個消息具有不同的折疊鍵。如果超過此數量,FCM 只會保留四個折疊鍵,無法保證保留哪些。

默認情況下,沒有有效負載的主題消息是可折疊的。

我應該使用哪個?

從性能的角度來看,可折疊消息是更好的選擇,前提是您的應用不需要使用不可折疊消息。但是,如果您使用可折疊消息,請記住,在任何給定時間,FCM 僅允許每個註冊令牌最多使用四個不同的折疊鍵。您不得超過此數量,否則可能會導致不可預測的後果。

使用場景如何發送
不可折疊每條消息對客戶端應用都很重要,需要傳遞。默認情況下,除通知消息外,所有消息都是不可折疊的。
可折疊當有較新的消息呈現與客戶端應用程序無關的較舊的相關消息時,FCM 會替換較舊的消息。例如:用於從服務器啟動數據同步的消息,或過時的通知消息。在您的消息請求中設置適當的參數:
  • collapseKey在Android
  • apns-collapse-id在iOS
  • Topic上的Web
  • collapse_key遺留協議(所有平台)

設置消息的優先級

您有兩個選項可以為 Android 上的下游消息分配傳遞優先級:正常優先級和高優先級。正常和高優先級消息的傳遞是這樣工作的:

  • 正常優先。這是默認優先級數據消息。當應用程序處於前台時,會立即傳遞普通優先級消息。當設備處於打盹狀態時,交付可能會延遲以節省電池。對於時間敏感度較低的消息,例如新電子郵件通知、保持 UI 同步或在後台同步應用程序數據,請選擇正常傳遞優先級。

    當接收到Android上的請求後台數據同步為您的應用正常優先級的消息,你可以安排與任務的WorkManager來處理它,當網絡可用。

  • 高優先級。 FCM 嘗試立即傳遞高優先級消息,允許 FCM 服務在必要時喚醒睡眠設備並運行一些有限的處理(包括非常有限的網絡訪問)。高優先級消息通常會導致用戶與您的應用或其通知進行交互。如果 FCM 檢測到他們沒有檢測到的模式,則您的消息可能會被取消優先級。 Android的P推出應用備用水桶,限制FCM高優先級消息的數量,您可以發送到您的應用程序,不要在用戶使用你的應用程序或查看通知結果。如果在響應高優先級消息時以用戶可見的方式顯示通知,則該消息將不會消耗您的應用備用存儲桶配額。

    由於一小部分 Android 移動用戶使用高延遲網絡,因此請避免在顯示通知之前打開與服務器的連接。在允許的處理時間結束之前回調服務器可能對高延遲網絡上的用戶有風險。相反,將通知內容包含在 FCM 消息中並立即顯示。如果您需要同步在Android上的附加應用程序內的內容,你可以安排與任務的WorkManager來處理在後台。

以下是通過 FCM HTTP v1 協議發送的普通優先級消息的示例,用於通知雜誌訂閱者有新內容可供下載:

{
  "message":{
    "topic":"subscriber-updates",
    "notification":{
      "body" : "This week's edition is now available.",
      "title" : "NewsMagazine.com",
    },
    "data" : {
      "volume" : "3.21.15",
      "contents" : "http://www.news-magazine.com/world-week/21659772"
    },
    "android":{
      "priority":"normal"
    },
    "apns":{
      "headers":{
        "apns-priority":"5"
      }
    },
    "webpush": {
      "headers": {
        "Urgency": "high"
      }
    }
  }
}

有關設置消息優先級的更多特定於平台的詳細信息:

設置消息的生命週期

FCM 通常在消息發送後立即進行傳遞。然而,這可能並不總是可行的。例如,如果平台是 Android,則設備可能處於關閉、離線或不可用狀態。或者 FCM 可能會故意延遲消息以防止應用程序消耗過多資源並對電池壽命產生負面影響。

發生這種情況時,FCM 會存儲消息並在可行時盡快發送。雖然這在大多數情況下都沒有問題,但有些應用程序可能永遠不會發送遲到的消息。例如,如果消息是來電或視頻聊天通知,則僅在呼叫終止前的一小段時間內有意義。或者,如果消息是參加活動的邀請,則在活動結束後收到也無濟於事。

在 Android 和 Web/JavaScript 上,您可以指定消息的最長生命週期。該值必須是從 0 到 2,419,200 秒(28 天)的持續時間,它對應於 FCM 存儲和嘗試傳遞消息的最長時間。不包含此字段的請求默認最長期限為 4 週。

以下是此功能的一些可能用途:

  • 視頻聊天來電
  • 即將到期的邀請事件
  • 日曆事件

指定消息生命週期的另一個優點是 FCM 從不限制生存時間值為 0 秒的消息。換句話說,FCM 保證對必須“現在或永遠”傳遞的消息做出最大努力。請記住,一個time_to_live無法立即送達0表示郵件的價值將被丟棄。但是,由於此類消息從不存儲,因此這為發送通知消息提供了最佳延遲。

下面是一個包含 TTL 的請求示例:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "data":{
      "Nick" : "Mario",
      "body" : "great match!",
      "Room" : "PortugalVSDenmark"
    },
    "apns":{
      "headers":{
        "apns-expiration":"1604750400"
      }
    },
    "android":{
      "ttl":"4500s"
    },
    "webpush":{
      "headers":{
        "TTL":"4500"
      }
    }
  }
}

接收來自多個發件人的消息

FCM 允許多方向同一個客戶端應用程序發送消息。例如,假設客戶端應用程序是具有多個貢獻者的文章聚合器,並且每個貢獻者都應該能夠在發布新文章時發送消息。此消息可能包含一個 URL,以便客戶端應用程序可以下載文章。 FCM 不必將所有發送活動集中在一個位置,而是讓您能夠讓每個貢獻者發送自己的消息。

要啟用此功能,請確保您有每個發送者的發送者ID 。請求註冊時,客戶端應用程序多次獲取令牌,每次在受眾字段中使用不同的發件人 ID,使用給定平台的令牌檢索方法:

請確保你沒有多發件人ID添加到一個單一的令牌請求,因為這樣可以有不可預知的結果。單獨撥打每個電話,每個發件人 ID 一次。

最後,與相應的發件人共享註冊令牌,他們將能夠使用自己的身份驗證密鑰向客戶端應用程序發送消息。

請注意,有 100 個多個發件人的限制。

消息的生命週期

當應用服務器向 FCM 發布消息並收到消息 ID 時,並不意味著消息已經傳送到設備。相反,這意味著它已被接受交付。消息被接受後會發生什麼取決於許多因素。

在最好的情況下,如果設備連接到 FCM,屏幕打開並且沒有節流限制,消息會立即傳遞。

如果設備已連接但處於 Doze 狀態,則 FCM 會存儲一條低優先級消息,直到設備處於 Doze 狀態。而這也正是collapse_key標誌起到了重要作用:如果已經有存儲等待傳送相同的崩潰鍵(註冊標記)的消息,舊的消息被丟棄,新的消息取代其位置(也就是老消息被新消息折疊)。但是,如果未設置折疊鍵,則會存儲新消息和舊消息以供將來傳遞。

如果設備未連接到 FCM,則會存儲消息,直到建立連接(再次遵守折疊密鑰規則)。建立連接後,FCM 會將所有待處理消息傳送到設備。如果設備再也無法連接(例如,如果它被恢復出廠設置),消息最終會超時並從 FCM 存儲中丟棄。默認的超時時間是四周,除非time_to_live標誌設置。

要更深入地了解消息的傳遞:

    為了更深入地了解Android或iOS上消息的傳遞,看到FCM報告信息中心,它記錄了發送信息的數量和開設在iOS和Android設備,與數據一起進行“印象”(通知用戶看到)的Android應用。

對於啟用了直接通道消息的 Android 設備,如果設備超過 1 個月未連接到 FCM,FCM 仍會接受該消息,但會立即將其丟棄。如果設備中的四個週裡,你發送給它的最後一個數據消息的內連接,您的客戶端接收onDeletedMessages()回調。然後應用程序可以正確處理這種情況,通常是通過從應用程序服務器請求完全同步。

最後,當 FCM 嘗試向設備發送消息並且應用程序被卸載時,FCM 會立即丟棄該消息並使註冊令牌無效。未來試圖將消息發送到該設備導致NotRegistered錯誤。

限制和縮放

我們的目標是始終傳遞通過 FCM 發送的每條消息。但是,傳遞每條消息有時會導致整體用戶體驗不佳。在其他情況下,我們需要提供邊界以確保 FCM 為所有發件人提供可擴展的服務。

可折疊消息限制

如上所述,可折疊消息是旨在折疊在彼此之上的無內容通知。如果開發人員過於頻繁地向應用重複相同的消息,我們會延遲(節流)消息以減少對用戶電池的影響。

例如,如果您向單個設備發送大量新的電子郵件同步請求,我們可能會將下一個電子郵件同步請求延遲幾分鐘,以便設備能夠以較低的平均速率同步。這種節流是嚴格進行的,以限制用戶體驗到的電池影響。

如果您的用例需要高突發發送模式,那麼不可折疊的消息可能是正確的選擇。對於此類消息,請確保在此類消息中包含內容以降低電池成本。

我們將可折疊消息限制為每台設備每個應用程序 20 條消息的突發,每 3 分鐘重新填充 1 條消息。

XMPP 服務器限制

我們將您可以連接到 FCM XMPP 服務器的速率限制為每個項目每分鐘 400 個連接。這應該不是消息傳遞的問題,但對於確保我們系統的穩定性很重要。

對於每個項目,FCM 允許 2500 個並行連接。

單個設備的最大消息速率

您最多可以向單個設備發送 240 條消息/分鐘和 5,000 條消息/小時。這個高閾值是為了允許短期流量突發,例如當用戶通過聊天快速交互時。此限制可防止發送邏輯中的錯誤無意中耗盡設備上的電池電量。

上行消息限制

我們限制上游消息在每個項目,以避免過載上行目標服務器150萬/分鐘。

我們將每台設備的上游消息限制為 1,000/分鐘,以防止電池因不良應用行為而耗盡。

主題消息限制

主題訂閱添加/刪除速率限制為每個項目 3,000 QPS。

對於消息發送速率,請參見扇出節流

扇出節流

消息扇出是將消息發送到多個設備的過程中,例如當你指定主題和組,或作為當您使用通知作曲家到目標受眾或用戶段。

消息扇出不是即時的,因此有時您會同時進行多個扇出。我們將每個項目的並發消息扇出數限制為 1,000。之後,我們可能會拒絕額外的扇出請求或推遲請求的扇出,直到一些已經在進行的扇出完成。

實際可實現的扇出率受同時請求扇出的項目數量的影響。單個項目 10,000 QPS 的扇出率並不少見,但該數字並不能保證,而是系統總負載的結果。請務必注意,可用扇出容量在項目之間分配,而不是跨扇出請求分配。因此,如果您的項目有兩個正在進行的扇出,那麼每個扇出只會看到可用扇出率的一半。最大化扇出速度的推薦方法是一次只進行一個活動扇出。

FCM 端口和您的防火牆

如果您的組織有防火牆來限制進出 Internet 的流量,您需要將其配置為允許移動設備與 FCM 連接,以便您網絡上的設備接收消息。 FCM 通常使用端口 5228,但有時也會使用 443、5229 和 5230。

對於連接到您網絡上的設備,FCM 不提供特定 IP,因為我們的 IP 範圍變化過於頻繁,您的防火牆規則可能會過時,從而影響您的用戶體驗。理想情況下,許可名單端口 5228-5230 和 443 沒有 IP 限制。但是,如果你必須有一個IP限制,你應該允許列表中列出的所有IP地址的goog.json 。這個大列表會定期更新,建議您每月更新規則。防火牆 IP 限制導致的問題通常是間歇性的,難以診斷。

我們確實提供了一組可以列入許可名單的域名,而不是 IP 地址。下面列出了這些主機名。如果我們開始使用其他主機名,我們將在此處更新列表。將域名用於您的防火牆規則可能會或可能不會在您的防火牆設備中起作用。

要開放的端口:

  • 5228
  • 5229
  • 5230
  • 443

要打開的主機名:

  • mtalk.google.com
  • mtalk4.google.com
  • mtalk-staging.google.com
  • mtalk-dev.google.com
  • alt1-mtalk.google.com
  • alt2-mtalk.google.com
  • alt3-mtalk.google.com
  • alt4-mtalk.google.com
  • alt5-mtalk.google.com
  • alt6-mtalk.google.com
  • alt7-mtalk.google.com
  • alt8-mtalk.google.com
  • android.clients.google.com
  • device-provisioning.googleapis.com

網絡地址轉換和/或狀態包檢測防火牆:

如果您的網絡實施網絡地址轉換 (NAT) 或狀態數據包檢查 (SPI),請為我們通過端口 5228-5230 的連接實施 30 分鐘或更長時間的超時。這使我們能夠提供可靠的連接,同時減少用戶移動設備的電池消耗。

證書

根據您實施的 FCM 功能,您可能需要 Firebase 項目中的以下憑據:

項目編號Firebase 項目的唯一標識符,用於對 FCM v1 HTTP 端點的請求。該值在可用火力地堡控制台設置面板。
註冊令牌

標識每個客戶端應用程序實例的唯一令牌字符串。單個設備和設備組消息傳遞需要註冊令牌。請注意,註冊令牌必須保密。

發件人ID當你創建你的火力地堡的項目,在可用的唯一數值創建雲端通訊的火力地堡控制台設置面板的選項卡。發件人 ID 用於標識可以向客戶端應用程序發送消息的每個發件人。
訪問令牌一種短期 OAuth 2.0 令牌,用於授權對 HTTP v1 API 的請求。此令牌與屬於您的 Firebase 項目的服務帳號相關聯。要創建和旋轉訪問令牌,請按照所描述的步驟授權發送請求
服務器密鑰(用於舊協議)

授權您的應用服務器訪問 Google 服務的服務器密鑰,包括通過 Firebase 雲消息傳遞舊協議發送消息。您在創建 Firebase 項目時獲取服務器密鑰。您可以在查看雲端通訊的火力地堡控制台設置面板的選項卡。

重要提示:不要在您的客戶端代碼服務器密鑰的任何地方。此外,請確保僅使用服務器密鑰來授權您的應用服務器。 FCM 拒絕 Android、iOS 和瀏覽器密鑰。