關於 FCM 消息

Firebase 雲端訊息傳遞 (FCM) 提供廣泛的訊息傳遞選項和功能。本頁中的資訊旨在幫助您了解不同類型的 FCM 訊息以及您可以使用它們執行哪些操作。

訊息類型

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

  • 通知訊息,有時被認為是「顯示訊息」。這些由 FCM SDK 自動處理。
  • 數據訊息,由客戶端應用程式處理。

通知訊息包含一組預先定義的使用者可見鍵。相較之下,資料訊息僅包含使用者定義的自訂鍵值對。通知訊息可以包含可選的資料負載。兩種訊息類型的最大負載均為 4000 字節,從 Firebase 控制台發送訊息時除外,該控制台強制執行 1000 個字元的限制。

使用場景如何發送
通知訊息當客戶端應用程式在背景執行時,FCM SDK 代表客戶端應用程式向最終用戶裝置顯示訊息。否則,如果收到通知時應用程式正在前台運行,則應用程式的程式碼將確定行為。通知訊息具有一組預先定義的使用者可見鍵和自訂鍵值對的選用資料負載。
  1. 在受信任的環境(例如Cloud Functions或應用程式伺服器)中,使用Admin SDK 或 HTTP v1 API 。設定notification鍵。可能有可選的資料負載。始終可折疊。

    請參閱顯示通知和發送請求負載的一些範例

  2. 使用通知編輯器:輸入訊息文字、標題等,然後發送。透過提供自訂資料來新增可選資料負載。
數據資訊客戶端應用程式負責處理資料訊息。資料訊息僅具有自訂鍵值對,沒有保留鍵名稱(見下文)。在受信任的環境(例如Cloud Functions或應用程式伺服器)中,使用Admin SDK 或 FCM 伺服器協定。在發送請求中,設定data密鑰。

當您希望 FCM SDK 在您的應用程式在背景執行時自動顯示通知時,請使用通知訊息。當您想要使用自己的客戶端應用程式程式碼處理訊息時,請使用資料訊息。

FCM 可以傳送包含可選資料有效負載的通知訊息。在這種情況下,FCM 處理顯示通知負載,而用戶端應用程式處理資料負載。

通知訊息

為了進行測試或行銷和重新吸引用戶,您可以使用 Firebase 控制台 發送通知訊息。 Firebase 控制台提供基於分析的A/B 測試,可協助您完善並改善行銷資訊。

若要使用 Admin SDK 或 FCM 協定以程式設計方式傳送通知訊息,請為通知訊息的使用者可見部分設定具有必要的預定義鍵值選項集的notification鍵。例如,以下是 IM 應用程式中的 JSON 格式的通知訊息。用戶可以期待看到標題為“葡萄牙 vs. 丹麥”和文字“偉大的比賽!”的訊息。在設備上:

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

當應用程式處於背景時,通知訊息將發送到通知托盤。對於前台應用程序,訊息由回調函數處理。

有關可用於建置通知訊息的預先定義鍵的完整列表,請參閱HTTP v1 協定通知物件參考文件。

數據資訊

使用自訂鍵值對設定適當的鍵,以將資料負載傳送到客戶端應用程式。

例如,下面是與上面相同的 IM 應用程式中的 JSON 格式的訊息,其中資訊封裝在公共data金鑰中,並且客戶端應用程式應解釋內容:

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

上面的範例顯示了頂級或公共data欄位的用法,該欄位由接收訊息的所有平台上的客戶端進行解釋。在每個平台上,客戶端應用程式都會在回調函數中接收資料有效負載。

資料訊息加密

Android 傳輸層(請參閱FCM 架構)使用點對點加密。根據您的需要,您可能決定在資料訊息中新增端對端加密。 FCM 不提供端到端解決方案。但是,有可用的外部解決方案,例如CapillaryDTLS

帶有可選資料負載的通知訊息

您可以透過程式設計方式或透過 Firebase 控制台傳送包含自訂鍵值對的選用負載的通知訊息。在通知編輯器中,使用進階選項中的自訂資料欄位。

接收包含通知和資料負載的訊息時的應用程式行為取決於應用程式是在背景還是前台,本質上取決於它在接收時是否處於活動狀態。

  • 在背景時,應用程式會在通知托盤中接收通知負載,並且僅在使用者點擊通知時處理資料負載。
  • 當在前台時,您的應用程式會收到一個包含兩個可用負載的訊息物件。

以下是包含notification金鑰和data金鑰的 JSON 格式的訊息:

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

跨平台自訂訊息

Firebase Admin SDK 和 FCM v1 HTTP 協定都允許您的訊息請求設定message物件中的所有可用欄位。這包括:

  • 由接收訊息的所有應用程式實例解釋的一組通用欄位。
  • 特定於平台的字段集,例如AndroidConfigWebpushConfig ,僅由在指定平台上運行的應用實例解釋。

特定於平台的區塊可讓您靈活地為不同平台自訂訊息,以確保在收到訊息時正確處理訊息。 FCM 後端將考慮所有指定的參數並為每個平台自訂訊息。

何時使用公共字段

當您處於以下情況時,請使用通用欄位:

  • 定位所有平台上的應用程式實例 - Apple、Android 和 Web
  • 向主題發送訊息

所有應用程式實例,無論平台如何,都可以解釋以下公共欄位:

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

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

  • 僅將欄位傳送到特定平台
  • 除了公共字段之外,還發送特定於平台的字段

每當您只想將值傳送到特定平台時,請不要使用公共欄位;使用特定於平台的字段。例如,要僅向 Apple 平台和 Web 發送通知,而不是向 Android 發送通知,您必須使用兩組獨立的字段,一組用於 Apple,一組用於 Web。

當您發送具有特定傳遞選項的訊息時,請使用特定於平台的欄位來設定它們。如果需要,您可以為每個平台指定不同的值。但是,即使您想要跨平台設定基本相同的值,也必須使用特定於平台的欄位。這是因為每個平台對該值的解釋可能略有不同 - 例如,在 Android 上,生存時間設定為以秒為單位的到期時間,而在 Apple 上,則將其設定為到期日期

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

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

  • 為 Android 和 Web 平台設定較長的生存時間,同時將 APNs(Apple 平台)訊息優先順序設定為較低設定
  • 設定適當的按鍵來定義使用者在 Android 和 Apple 上點選通知的結果 - 分別是click_actioncategory
{
  "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 裝置的訊息提供了一組特定的傳遞選項,並允許在 Apple 平台和 Web 上使用類似的選項。例如,在Android上透過FCM的collapse_key支援「可折疊」訊息行為,在Apple上透過apns-collapse-id支持,在JavaScript/Web上透過Topic支援。詳情請參閱本節的描述以及相關參考文件。

不可折疊和可折疊訊息

不可折疊訊息表示每個單獨的訊息都傳遞到裝置。與可折疊訊息不同,不可折疊訊息會傳遞一些有用的內容,例如向行動應用程式發送無內容「ping」以聯繫伺服器以獲取資料。

不可折疊訊息的一些典型用例是聊天訊息或關鍵訊息。例如,在 IM 應用程式中,您可能希望傳遞每個訊息,因為每個訊息都有不同的內容。

對於 Android,在不崩潰的情況下可以儲存的訊息數量上限為 100 條。如果達到限制,所有儲存的訊息將被丟棄。當設備重新連線時,它會收到一條特殊訊息,指示已達到限制。然後,應用程式可以正確處理這種情況,通常是透過從應用程式伺服器請求完全同步。

可折疊訊息是如果尚未傳送到設備則可以被新訊息取代的訊息。

可折疊訊息的常見用例是用於告訴行動應用程式從伺服器同步資料的訊息。一個例子是向用戶更新最新得分的體育應用程式。只有最新的消息才是相關的。

若要將訊息在 Android 上標記為可折疊,請在訊息負載中包含collapse_key參數。預設情況下,折疊鍵是在 Firebase 控制台中註冊的應用程式套件名稱。 FCM 伺服器可以在每個裝置上同時儲存四個不同的可折疊訊息,每個訊息都有不同的折疊金鑰。如果超過此數量,FCM 僅保留四個折疊鍵,且不保證保留哪些按鍵。

沒有負載的主題訊息預設是可折疊的。通知訊息始終是可折疊的,並且會忽略collapse_key參數。

我該使用哪一個?

從效能的角度來看,可折疊訊息是更好的選擇,前提是您的應用程式不需要使用不可折疊訊息。但是,如果您使用可折疊訊息,請記住,FCM 在任何給定時間僅允許每個註冊令牌最多使用四個不同的折疊鍵。絕對不能超過這個數字,否則可能會造成不可預測的後果。

使用場景如何發送
不可折疊每個訊息對於客戶端應用程式都很重要並且需要傳遞。除通知訊息外,所有訊息預設都是不可折疊的。
可折疊當較新的訊息呈現與用戶端應用程式無關的較舊的相關訊息時,FCM 會取代較舊的訊息。例如:用於從伺服器啟動資料同步的訊息,或過時的通知訊息。在訊息請求中設定適當的參數:
  • Android 上的collapseKey
  • Apple 上的apns-collapse-id
  • 網路Topic
  • 遺留協定中的collapse_key (所有平台)

設定訊息的優先級

您有兩個選項可以為下游訊息指派傳送優先權:正常優先權和高優先權。儘管不同平台的行為略有不同,但正常和高優先級訊息的傳遞工作原理如下:

  • 正常優先級。當應用程式位於前台時,會立即傳遞普通優先級訊息。對於後台應用程序,交付可能會延遲。對於時間敏感度較低的訊息,例如新電子郵件通知、保持 UI 同步或在背景同步應用程式數據,請選擇正常傳送優先順序。

  • 高優先級。即使裝置處於 Doze 模式,FCM 也會嘗試立即傳遞高優先權訊息。高優先權訊息適用於時間敏感、使用者可見的內容。

以下是透過 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 儲存並嘗試傳遞訊息的最長時間段。不包含此欄位的請求預設最長期限為四週。

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

  • 視訊通訊來電
  • 即將過期的邀請活動
  • 日曆事件

指定訊息的生命週期的另一個優點是 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 發送訊息並收到傳回的訊息 ID 時,並不表示該訊息已傳遞到裝置。相反,這意味著它已被接受交付。訊息被接受後會發生什麼取決於許多因素。

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

如果裝置已連線但處於打瞌睡狀態,則 FCM 會儲存一條低優先權訊息,直到裝置退出打瞌睡狀態。這就是collapse_key標誌發揮作用的地方:如果已經儲存了具有相同折疊鍵(和註冊令牌)的訊息並等待傳遞,則舊訊息將被丟棄,新訊息將取代它(即舊訊息)。訊息被新訊息折疊)。但是,如果未設定折疊鍵,則新訊息和舊訊息都會儲存以供將來傳遞。

如果裝置未連接到 FCM,則訊息將被存儲,直到建立連接為止(再次遵守折疊金鑰規則)。建立連線後,FCM 將所有待處理訊息傳送到裝置。如果設備再也無法連接(例如,恢復原廠設定),訊息最終會逾時並從 FCM 儲存中丟棄。預設超時為四個星期,除非設定了time_to_live標誌。

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

    若要更深入了解 Android 或 Apple 平台上的消息傳遞情況,請參閱FCM 報告儀表板,其中記錄了 Apple 和 Android 裝置上發送和開啟的訊息數量,以及「展示次數」(使用者看到的通知)數據安卓應用程式。

對於啟用了直接通道訊息傳遞的 Android 設備,如果設備超過 1 個月沒有連接到 FCM,FCM 仍會接受該訊息,但會立即丟棄該訊息。如果裝置在您傳送最後一封資料訊息後四週內連接,您的用戶端會收到onDeletedMessages()回呼。然後,應用程式可以正確處理這種情況,通常是透過從應用程式伺服器請求完全同步。

最後,當 FCM 嘗試向裝置傳遞訊息並且應用程式已卸載時,FCM 會立即丟棄該訊息並使註冊令牌失效。以後嘗試向該裝置發送訊息會導致NotRegistered錯誤。

節流和縮放

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

可折疊訊息限制

如上所述,可折疊訊息是設計為相互折疊的無內容通知。如果開發人員過於頻繁地向應用程式重複相同的訊息,我們會延遲(限制)訊息以減少對用戶電池的影響。

例如,如果您向單一裝置發送大量新電子郵件同步請求,我們可能會將下一個電子郵件同步請求延遲幾分鐘,以便裝置能夠以較低的平均速率同步。嚴格執行此限制是為了限制用戶所經歷的電池影響。

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

我們將可折疊訊息的突發數量限制為每個裝置每個應用程式最多 20 個訊息,並且每 3 分鐘補充 1 個訊息。

XMPP 伺服器限制

我們將每個項目可連接到 FCM XMPP 伺服器的速率限制為每分鐘 400 個連線。這對於訊息傳遞來說應該不是問題,但對於確保系統的穩定性很重要。對於每個項目,FCM 允許並行 2500 個連線。

對於使用 XMPP 的上游訊息傳遞,FCM 將每個專案的上游訊息限制為 1,500,000 條/分鐘,以避免上游目標伺服器過載。

我們將每台裝置的上游訊息限制為 1,000 條/分鐘,以防止不良應用行為導致電池耗盡。

單一裝置的最大訊息速率

對於 Android,您可以向單一裝置發送最多 240 則訊息/分鐘和 5,000 則訊息/小時。這個高閾值是為了允許短期流量爆發,例如當使用者透過聊天快速互動時。此限制可防止發送邏輯中的錯誤無意中耗盡裝置上的電池。

對於 iOS,當速率超過 APNs 限制時,我們會傳回錯誤。

主題留言限制

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

有關訊息發送速率,請參閱扇出限制

扇出節流

訊息扇出是將訊息傳送到多個裝置的過程,例如當您定位主題和群組時,或當您使用通知編輯器來定位受眾或使用者群組時。

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

實際可實現的扇出率受到同時請求扇出的項目數量的影響。單一項目的扇出率為 10,000 QPS 並不罕見,但該數字並不能保證,而是系統總負載的結果。值得注意的是,可用的扇出容量是在項目之間劃分的,而不是在扇出請求之間劃分的。因此,如果您的專案正在進行兩個扇出,則每個扇出只能看到可用扇出率的一半。最大化扇出速度的建議方法是一次僅進行一個活動扇出。

FCM 連接埠和您的防火牆

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

對於連接到您網路上的設備,FCM 不提供特定 IP,因為我們的 IP 範圍變更過於頻繁,且您的防火牆規則可能會過時,影響您的使用者體驗。理想情況下,將連接埠 5228-5230 和 443 列入白名單,沒有 IP 限制。但是,如果您必須有 IP 限制,則應將goog.json中列出的所有 IP 位址列入白名單。這個大列表會定期更新,建議您每月更新一次規則。防火牆 IP 限制所引起的問題通常是間歇性的且難以診斷。

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

要開啟的 TCP 連接埠:

  • 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.apis.google.com
  • device-provisioning.googleapis.com
  • firebaseinstallations.googleapis.com

網路位址轉換和/或狀態資料包偵測防火牆:

如果您的網路實施網路位址轉換 (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 舊協定發送訊息。

重要提示:請勿在客戶端程式碼中的任何位置包含伺服器金鑰。另外,請確保僅使用伺服器金鑰來授權您的應用程式伺服器。 Android、Apple 平台和瀏覽器金鑰被 FCM 拒絕。