Firebase雲消息傳遞(FCM)提供了廣泛的消息傳遞選項和功能。此頁面中的信息旨在幫助您了解FCM消息的不同類型以及如何使用它們。
訊息類型
使用FCM,您可以向客戶端發送兩種類型的消息:
- 通知消息,有時被稱為“顯示消息”。這些由FCM SDK自動處理。
- 數據消息,由客戶端應用處理。
通知消息包含一組預定義的用戶可見鍵。相反,數據消息僅包含用戶定義的自定義鍵值對。通知消息可以包含可選的數據有效載荷。兩種消息類型的最大有效負載均為4KB,但從Firebase控制台發送消息(強制實施1024個字符限制)時除外。
使用場景 | 如何發送 | |
---|---|---|
通知訊息 | FCM代表客戶端應用程序自動將消息顯示給最終用戶設備。通知消息具有一組預定義的用戶可見鍵和一個自定義鍵值對的可選數據有效載荷。 |
|
數據信息 | 客戶端應用負責處理數據消息。數據消息僅具有自定義鍵值對,而沒有保留鍵名(請參見下文)。 | 在諸如Cloud Functions或您的應用服務器之類的受信任環境中,請使用Admin SDK或FCM服務器協議:僅設置data 密鑰。 |
當您希望FCM處理代表客戶端應用程序顯示的通知時,請使用通知消息。當您要在客戶端應用程序上處理消息時,請使用數據消息。
FCM可以發送包括可選數據有效載荷的通知消息。在這種情況下,FCM會處理顯示通知有效負載,而客戶端應用程序會處理數據有效負載。
通知訊息
為了進行測試或進行市場營銷和用戶重新參與,您可以使用Firebase控制台發送通知消息。 Firebase控制台提供基於分析的A / B測試,以幫助您完善和改善營銷信息。
要使用Admin SDK或FCM協議以編程方式發送通知消息,請為通知消息的用戶可見部分設置必要的鍵值選項預定義的notification
密鑰。例如,這是IM應用程序中的JSON格式的通知消息。用戶可能希望看到一條消息,標題為“葡萄牙與丹麥”,文本為“大比拼!”。在設備上:
{ "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不提供端到端解決方案。但是,有可用的外部解決方案,例如Capillary或DTLS 。
帶有可選數據有效載荷的通知消息
無論是通過編程方式還是通過Firebase控制台,您都可以發送包含自定義鍵值對的可選有效負載的通知消息。在“通知”編輯器中,使用“高級”選項中的“自定義數據”字段。
接收包含通知和數據有效負載的消息時,應用程序的行為取決於該應用程序是在後台還是在前台,本質上取決於接收時該應用程序是否處於活動狀態。
- 在後台時,應用程序會在通知托盤中接收通知有效載荷,並且僅在用戶點擊通知時處理數據有效載荷。
- 在前台時,您的應用程序會收到一個消息對象,其中包含兩個有效負載。
這是包含notification
鍵和data
鍵的JSON格式的消息:
{ "message":{ "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification":{ "title":"Portugal vs. Denmark", "body":"great match!" }, "data" : { "Nick" : "Mario", "Room" : "PortugalVSDenmark" } } }
跨平台自定義消息
在火力地堡管理SDK和FCM V1 HTTP協議都允許你的信息請求中設置的所有可用字段message
的對象。這包括:
- 接收消息的所有應用程序實例將解釋的一組通用字段。
- 特定於平台的字段集,例如
AndroidConfig
和WebpushConfig
,僅由在指定平台上運行的應用程序實例解釋。
特定於平台的塊使您可以靈活地針對不同平台自定義消息,以確保在收到消息後正確處理它們。 FCM後端將考慮所有指定的參數,並為每個平台自定義消息。
何時使用通用字段
在以下情況下,請使用常見字段:
- 在所有平台(iOS,Android和Web)上定位應用程序實例
- 向主題發送消息
無論平台如何,所有應用程序實例都可以解釋以下公共字段:
何時使用平台特定字段
當您要執行以下操作時,請使用特定於平台的字段:
- 僅將字段發送到特定平台
- 除常見字段外,還發送特定於平台的字段
每當您只想將值發送到特定平台時,都不要使用公共字段。使用特定於平台的字段。例如,要僅向iOS和Web發送通知,而不向Android發送通知,則必須使用兩組單獨的字段,一組用於iOS,另一組用於Web。
當您發送帶有特定傳遞選項的郵件時,請使用特定於平台的字段進行設置。如果需要,可以為每個平台指定不同的值。但是,即使您想在各個平台上設置基本相同的值,也必須使用特定於平台的字段。這是因為每個平台對值的解釋都略有不同-例如,將生存時間在Android上設置為以秒為單位的到期時間,而在iOS上將其設置為到期日期。
示例:帶有特定於平台的傳遞選項的通知消息
以下v1發送請求將通用通知標題和內容髮送到所有平台,但還會發送一些特定於平台的替代。具體來說,該請求:
- 為Android和Web平台設置了較長的生存時間,同時將APN(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
參數。 FCM允許在任何給定時間,每台Android設備最多由應用服務器使用四個不同的折疊鍵。換句話說,FCM服務器可以為每個設備同時存儲四個不同的可折疊消息,每個消息具有不同的折疊密鑰。如果超過此數字,FCM僅保留四個折疊鍵,而不能保證保留哪個折疊鍵。
默認情況下,沒有有效載荷的主題消息是可折疊的。
我應該使用哪個?
從性能的角度來看,可折疊消息是更好的選擇,前提是您的應用不需要使用非可折疊消息。但是,如果您使用可折疊消息,請記住,FCM在任何給定時間只允許每個註冊令牌的FCM連接服務器最多使用四個不同的折疊密鑰。您不得超過此數字,否則可能會導致不可預測的後果。
使用場景 | 如何發送 | |
---|---|---|
不可折疊 | 每條消息對客戶端應用都很重要,需要傳遞。 | 除通知消息外,所有消息在默認情況下都是不可折疊的。 |
可折疊 | 如果有較新的消息使較舊的相關消息與客戶端應用程序無關,則FCM會替換較舊的消息。例如:用於從服務器啟動數據同步的消息,或過時的通知消息。 | 在您的消息請求中設置適當的參數:
|
設置消息的優先級
您可以通過以下兩種方法為Android上的下游消息分配傳遞優先級:普通優先級和高優先級。正常和高優先級消息的傳遞是這樣的:
正常優先級。這是數據消息的默認優先級。當應用程序位於前台時,普通優先級消息會立即傳遞。當設備處於打ze狀態時,可能會延遲交貨以節省電池。對於對時間不太敏感的消息(例如,新電子郵件的通知,使您的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" } } } }
有關設置消息優先級的更多特定於平台的詳細信息,請執行以下操作:
- APNs文檔
- 針對打ze和應用待機進行優化(Android)
- 網頁推送消息的緊急性
設置消息的壽命
FCM通常在發送郵件後立即發送郵件。但是,這並不總是可能的。例如,如果平台是Android,則該設備可能已關閉,處於脫機狀態或不可用。或者FCM可能有意延遲消息,以防止應用程序消耗過多的資源並對電池壽命造成負面影響。
發生這種情況時,FCM將存儲消息並在可行的情況下盡快將其傳遞。儘管在大多數情況下這很好,但對於某些應用程序,也可能永遠不會傳遞最新消息。例如,如果消息是來電或視頻聊天通知,則僅在終止呼叫之前的短時間內有意義。或者,如果該消息是對事件的邀請,則在事件結束後接收到該消息是沒有用的。
在Android和Web / JavaScript上,您可以指定消息的最大壽命。該值的持續時間必須為0到2,419,200秒(28天),並且它對應於FCM存儲和嘗試傳遞消息的最大時間段。不包含此字段的請求默認最長為四個星期。
這是此功能的一些可能用途:
- 視頻聊天來電
- 邀請活動即將過期
- 日曆活動
指定消息壽命的另一個好處是,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:
- iOS(Swift)—
token(completion:)
- Android —
FirebaseMessaging.getInstance().getToken()
確保您沒有將多個發件人ID添加到單個令牌請求中,因為這可能會產生不可預測的結果。每個發件人ID分別撥打一次電話。
最後,與相應的發件人共享註冊令牌,他們將能夠使用其自己的身份驗證密鑰向客戶端應用發送消息。
請注意,最多可以有100個多個發件人。
訊息的生命週期
當應用服務器將消息發佈到FCM並收到消息ID時,這並不意味著該消息已經傳遞到設備。相反,這意味著它已被接受交付。郵件被接受後會發生什麼情況取決於許多因素。
在最佳情況下,如果設備已連接到FCM,則屏幕處於打開狀態,並且沒有節流限制,消息將立即發送。
如果設備已連接但處於打ze狀態,則FCM將存儲低優先級消息,直到設備退出打out狀態為止。這就是collapse_key
標誌起作用的地方:如果已經存儲了一條具有相同折疊鍵(和註冊令牌)的消息並等待發送,則舊消息將被丟棄,而新消息將取代它(即舊消息)。郵件被新郵件折疊)。但是,如果未設置折疊鍵,則新消息和舊消息都將存儲以備將來發送。
如果設備未連接到FCM,則消息將一直存儲到建立連接為止(再次遵守折疊鍵規則)。建立連接後,FCM會將所有未決消息傳遞到設備。如果設備再也無法連接(例如,如果它已恢復出廠設置),則該消息最終將超時並從FCM存儲器中丟棄。除非設置了time_to_live
標誌,否則默認超時為四周。
要更深入地了解消息的傳遞,請執行以下操作:
對於啟用了直接頻道消息傳遞的Android設備,如果該設備未連接到FCM超過一個月,則FCM仍會接受該消息,但會立即將其丟棄。如果設備在發送給您的最後一條數據消息後的四周內連接,則客戶端將收到onDeletedMessages()回調。然後,應用通常可以通過從應用服務器請求完全同步來正確處理這種情況。
最終,當FCM嘗試將消息傳遞到設備並卸載了該應用程序時,FCM會立即丟棄該消息並使註冊令牌無效。將來嘗試向該設備發送消息會導致NotRegistered
錯誤。
節流和縮放
我們的目標是始終傳遞通過FCM發送的每條消息。但是,傳遞每條消息有時會導致整體用戶體驗不佳。在其他情況下,我們需要提供邊界以確保FCM為所有發送者提供可擴展的服務。
可折疊消息限制
如上所述,可折疊消息是設計為彼此折疊的無內容通知。如果開發人員過於頻繁地向應用重複發送相同的消息,我們會延遲(調整)消息以減少對用戶電池的影響。
例如,如果您將大量新的電子郵件同步請求發送到單個設備,我們可能會將下一個電子郵件同步請求延遲幾分鐘,以便該設備可以較低的平均速率進行同步。嚴格執行此節流措施是為了限制用戶遭受的電池衝擊。
如果您的用例需要高突發發送模式,則非可折疊消息可能是正確的選擇。對於此類消息,請確保將內容包括在此類消息中,以降低電池成本。
我們將可折疊消息限制為每台設備每個應用最多20條消息,每3分鐘重新填充1條消息。
XMPP服務器限制
我們將每個項目每分鐘可連接到FCM XMPP服務器的速率限制為每分鐘400個連接。對於郵件傳遞來說,這不應該是一個問題,但是對於確保系統的穩定性而言,這一點很重要。
對於每個項目,FCM允許並行進行2500個連接。
單個設備的最大消息速率
您最多可以將240條消息/分鐘和5,000條消息/小時發送到單個設備。此高閾值旨在允許短期流量突發,例如當用戶通過聊天快速交互時。此限制可防止由於發送邏輯錯誤而無意中耗盡設備上的電池。
上游消息限制
我們將每個項目的上游消息限制為1,500,000 /分鐘,以避免上游目標服務器超載。
我們將每台設備的上游消息限制為每分鐘1,000條,以防止因不良應用行為而浪費電池。
主題消息限制
每個項目的主題訂閱添加/刪除速率限制為3,000 QPS。
有關消息發送速率,請參見“扇出節流” 。
扇出節流
消息扇出是將消息發送到多個設備的過程,例如,當您定位主題和組時,或者在使用Notifications作曲器定位目標受眾或用戶群時。
消息扇出不是瞬時的,因此有時您同時進行多個扇出。我們將每個項目的並發消息扇出數量限制為1,000。之後,我們可能會拒絕其他的扇出請求或將請求的扇出推遲到一些已經在進行中的扇出完成為止。
實際可實現的扇出率受同時請求扇出的項目數量影響。單個項目的10,000 QPS扇出率並不少見,但這不是保證,而是系統總負載的結果。重要的是要注意,可用的扇出能力是在項目之間分配的,而不是在扇出請求之間分配的。因此,如果您的項目正在進行兩個扇出,則每個扇出只會看到可用扇出率的一半。建議使用最大扇出速度的方法是一次僅進行一個活動扇出。
FCM端口和防火牆
如果您的組織有防火牆來限制進出Internet的流量,則需要對其進行配置,以允許移動設備與FCM連接,以便網絡上的設備接收消息。 FCM通常使用端口5228,但有時使用5229和5230。
對於傳出連接,FCM不提供特定的IP,因為我們的IP範圍更改過於頻繁,並且您的防火牆規則可能會過時,從而影響您的用戶體驗。理想情況下,將白名單端口5228-5230設置為無IP限制。但是,如果必須設置IP限制,則應將goog.json中列出的所有IP地址列入白名單。此大型列表會定期更新,建議您每月更新一次規則。由防火牆IP限制引起的問題通常是間歇性的,很難診斷。
用於打開傳入消息的端口:
- 5228
- 5229
- 5230
- 443
允許傳出連接的端口:
其中之一(首選方法#1):
- 沒有IP限制
默認域的所有IP地址。
要檢索這些地址的最新列表,請按照IP地址中默認域中所述的說明進行操作。
網絡地址轉換和/或狀態數據包檢查防火牆:
如果您的網絡實現了網絡地址轉換(NAT)或狀態數據包檢查(SPI),請為5228-5230端口上的連接實施30分鐘或更長時間的超時。這使我們能夠提供可靠的連接,同時減少用戶移動設備的電池消耗。
證書
根據您實施的FCM功能,您可能需要Firebase項目中的以下憑據:
專案編號 | Firebase項目的唯一標識符,用於對FCM v1 HTTP端點的請求。該值在Firebase控制台的“設置”窗格中可用。 |
註冊令牌 | 唯一的令牌字符串,用於標識每個客戶端應用程序實例。對於單個設備和設備組消息傳遞,註冊令牌是必需的。請注意,註冊令牌必須保密。 |
發件人ID | 創建Firebase項目時創建的唯一數值,可在Firebase控制台“設置”窗格的“雲消息”選項卡中找到。發件人ID用於標識可以向客戶端應用發送消息的每個發件人。 |
訪問令牌 | 一種短暫的OAuth 2.0令牌,用於授權對HTTP v1 API的請求。該令牌與屬於您的Firebase項目的服務帳戶相關聯。要創建和輪換訪問令牌,請按照“授權發送請求”中所述的步驟進行操作。 |
服務器密鑰(用於舊協議) | 服務器密鑰,授權您的應用服務器訪問Google服務,包括通過Firebase Cloud Messaging舊協議發送消息。在創建Firebase項目時,您將獲得服務器密鑰。您可以在Firebase控制台“設置”窗格的“雲消息傳遞”選項卡中查看它。 重要說明:請勿在客戶端代碼中的任何位置包含服務器密鑰。另外,請確保僅使用服務器密鑰來授權您的應用服務器。 FCM拒絕Android,iOS和瀏覽器密鑰。 |