關於 FCM 訊息

Firebase 雲端通訊 (FCM) 提供多種通訊選項和功能。本網頁中的資訊旨在協助您瞭解不同類型的 FCM 訊息類型,以及您可以如何處理這些訊息。

訊息類型

透過 FCM,您可以將兩種類型的訊息傳送給用戶端:

  • 通知訊息,有時也稱為「顯示訊息」。並由 FCM SDK 自動處理。
  • 資料訊息,由用戶端應用程式處理。

通知訊息包含一組預先定義的使用者可見金鑰。資料訊息則只會包含使用者定義的自訂鍵/值組合。通知訊息可包含選用的資料酬載。兩種訊息類型的酬載上限都是 4, 096 位元組,但如果是從 Firebase 控制台傳送訊息,則強制設有 1, 000 個字元的限制。

使用情境 傳送方式
通知訊息 當用戶端應用程式在背景執行時,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 鍵。例如以下是即時訊息應用程式中的 JSON 格式通知訊息,使用者預期會在裝置上看到標題為「葡萄牙 vs. 丹麥」的訊息,以及文字「很棒!」:

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

當應用程式在背景執行時,通知訊息會傳送至通知匣。若是前景的應用程式,訊息會由回呼函式處理。

如需建構通知訊息的可用預先定義金鑰完整清單,請參閱 HTTP v1 通訊協定通知物件參考說明文件。

資料訊息

利用自訂鍵/值組合設定適當的鍵,將資料酬載傳送至用戶端應用程式。

舉例來說,以下是位於相同即時訊息應用程式中的 JSON 格式訊息,其中資訊已封裝在共用的 data 鍵中,且用戶端應用程式應可解讀內容:

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

以上範例顯示頂層 (或一般) data 欄位的用法,這個欄位是由用戶端在收到訊息的所有平台上解讀。在每個平台上,用戶端應用程式會透過回呼函式接收資料酬載。

資料訊息加密

Android 傳輸層 (請參閱 FCM 架構) 採用點對點加密。視您的需求而定,您可以決定是否要對資料訊息新增端對端加密功能。FCM 不提供端對端解決方案。不過,還有可用的外部解決方案,例如 CapillaryDTLS

含有選用資料酬載的通知訊息

您可以透過程式或 Firebase 控制台,傳送包含自訂鍵/值組合選用酬載的通知訊息。在 通知編輯器中,使用「進階選項」中的「Custom data」欄位。

接收包含通知和資料酬載的訊息時,應用程式的行為取決於應用程式是在背景或前景運作 (基本上,是在收到時是否運作)。

  • 在背景中,應用程式會在通知匣中接收通知酬載,且只有在使用者輕觸通知時才會處理資料酬載。
  • 在前景執行時,應用程式會收到含有兩個酬載的訊息物件。

以下是 JSON 格式的訊息,其中包含 notification 鍵和 data 鍵:

{
  "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 和網頁
  • 傳送訊息至主題

無論平台為何,所有應用程式執行個體都能解讀下列常見欄位:

平台專用欄位的使用時機

如要執行以下操作,請使用平台專屬欄位:

  • 僅將欄位傳送至特定平台
  • 除了一般欄位,也傳送平台專屬欄位

如果您只想將值傳送到特定平台,「請勿」使用一般欄位;請使用平台專屬欄位。舉例來說,如果只想傳送通知到 Apple 平台和網路,而不傳送至 Android,則必須使用兩組不同的欄位,分別用於 Apple 和網站。

傳送含有特定傳送選項的訊息時,請使用平台專用欄位來設定。如有需要,您可以為每個平台指定不同的值。不過,即使您想跨平台設定本質上相同的值,也必須使用平台專屬欄位。這是因為每個平台解讀這個值可能略有不同,例如,在 Android 上將使用時間設為以秒為單位的到期時間,而在 Apple 上則設定為到期時間 date

示例:包含平台專屬傳送選項的通知訊息

以下 v1 傳送要求會將通用通知標題和內容傳送至所有平台,但也會傳送部分平台專屬的覆寫設定。具體而言,要求:

  • 為 Android 和網頁平台設定長時間的存留時間,並將 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 平台和網路上進行類似選項。舉例來說,在 Android 上,透過 FCM 的 collapse_key 或在 Apple 中透過 apns-collapse-id 支援「可收合」的訊息行為,或是在 JavaScript/網站上透過 Topic 支援。如需詳細資訊,請參閱本節說明和相關參考說明文件。

無法收合及可收合的訊息

無法收合的訊息表示每則訊息傳送至裝置。無法收合的訊息傳遞一些有用的內容,而不是向行動應用程式發出「連線偵測 (ping)」等可收合訊息,聯絡伺服器來擷取資料。

無法收合訊息的常見用途包括即時通訊訊息或重要訊息。例如,在即時訊息應用程式中,由於每則訊息都包含不同的內容,因此您想要傳送每則訊息。

在 Android 中,最多可以在不收合的情況下儲存 100 則訊息。一旦達到限制,系統就會捨棄所有儲存的訊息。當裝置恢復連線時,就會收到特殊訊息,指出已達上限。隨後應用程式就能正確處理該情況,通常是向應用程式伺服器要求完整同步。

可收合訊息是指尚未傳送至裝置的訊息,可能會替換為新訊息。

可收合訊息的常見用途是讓行動應用程式從伺服器同步處理資料。舉例來說,一個運動應用程式會使用最新得分更新使用者。只有最新的訊息相關。

如要在 Android 中將訊息標示為可收合,請在訊息酬載中加入 collapse_key 參數。根據預設,收合金鑰是在 Firebase 控制台中註冊的應用程式套件名稱。FCM 伺服器可以針對每部裝置同時儲存四則不同的可收合訊息,每個訊息都有不同的收合鍵。如果超過這個數量,FCM 只會保留四個收合鍵,而無法保證會保留哪些鍵。

根據預設,沒有酬載的主題訊息可以收合。通知訊息一律可以收合,且會忽略 collapse_key 參數。

我該使用哪一種?

如果應用程式不需要使用無法收合的訊息,從效能的角度來看,可收合訊息是更好的選擇。然而,如果您使用可收合的訊息,請記得,每個註冊權杖在 FCM 任何特定時間點,最多都允許 FCM 使用四個不同的收合鍵。請勿超過這個數字,否則可能會造成無法預測的結果。

使用情境 傳送方式
不可收合 每則訊息對用戶端應用程式而言非常重要,必須傳送。 根據預設,除了通知訊息之外,所有訊息皆無法收合。
可折疊 如果有新的訊息會轉譯一則與用戶端應用程式無關的舊訊息,FCM 會取代較舊的訊息。例如:從伺服器啟動資料同步處理作業的訊息,或是過期的通知訊息。 在訊息要求中設定適當的參數:
  • collapseKey (Android 裝置)
  • Apple 上的《apns-collapse-id
  • Topic 網頁版
  • 舊版通訊協定 (所有平台) 中的 collapse_key

設定訊息的優先順序

針對下游訊息的傳送優先順序有兩種選項:一般和高優先順序。儘管各平台的行為方式略有不同,但一般和高優先順序訊息的傳送運作方式如下:

  • 一般優先順序。 一般優先訊息會在應用程式於前景運作時立即傳送。如果是背景應用程式,交付可能會延遲。如果你的訊息較不具時效性 (例如收到新電子郵件的通知、讓 UI 保持同步,或是在背景同步處理應用程式資料),請選擇一般傳送優先順序。

  • 高優先順序。即使裝置處於打盹模式,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 和網頁/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 應用程式的「曝光」(使用者看到的通知) 資料。

針對已啟用即時訊息功能的 Android 裝置,如果裝置超過 1 個月未與 FCM 連線,FCM 仍會接受訊息,但會立即捨棄。如果裝置在您上次傳送資料訊息的四週內連線,則用戶端會收到 onDeletedMessages() 回呼。隨後應用程式就能正確處理該情況,通常是向應用程式伺服器要求完整同步。

最後,當 FCM 嘗試傳送訊息至裝置,且應用程式已解除安裝時,FCM 會立即捨棄這則訊息,並將註冊權杖失效。且日後嘗試傳送訊息至該裝置時,系統會顯示 NotRegistered 錯誤。

節流與資源調度

我們的目標是持續傳送所有透過 FCM 傳送的訊息。不過,有時傳送每則訊息會導致整體使用者體驗不佳。在其他情況下,我們需要提供界線,確保 FCM 為所有寄件者提供可擴充的服務。

可收合訊息節流

如上所述,可收合的訊息是無內容的通知,設計目的在於收合彼此。如果開發人員太常重複對應用程式傳達相同訊息,我們會延遲 (節流) 訊息,減少對使用者電池的影響。

舉例來說,如果您向單一裝置傳送大量新的電子郵件同步要求,我們可能會將下一次電子郵件同步要求延遲幾分鐘,以便讓該裝置能夠以較低的平均頻率同步處理。系統會嚴格執行這項節流措施,以限制使用者對電池造成的影響。

如果您的用途需要高突發的傳送模式,那麼不可收合的訊息可能會是合適的選擇。針對這類訊息,請務必在這類訊息中加入內容,以便降低電池成本。

我們限制可收合訊息的每個裝置最多每 20 則訊息,而且每 3 分鐘重新填 1 則訊息。

XMPP 伺服器節流

我們限制了每個專案每分鐘可連線至 FCM XMPP 伺服器的速率。這應該不會對訊息傳送造成問題,但對於確保系統的穩定性至關重要。FCM 每個專案可並行 2500 個連線。

針對搭配 XMPP 的上游訊息,FCM 會限制每項專案每分鐘 1,500,000 次的上游訊息,以免超載上游目的地伺服器。

我們將每部裝置的上游訊息限制為每分鐘 1,000 次,以免電池出現不良行為。

單一裝置的訊息傳送頻率上限

以 Android 來說,您每小時最多可傳送 240 則訊息到單一裝置,最多 5,000 則訊息。這個高門檻的用意是讓短期的流量暴增,例如使用者在即時通訊中快速互動時。這項限制可防止傳送邏輯錯誤,避免裝置意外消耗電池電力。

如果是 iOS,系統會在頻率超過 APNs 限制時傳回錯誤。

主題訊息限制

每個專案的主題訂閱新增/移除率上限為 3,000 QPS。

如需訊息傳送速率的相關資訊,請參閱傳送速度限制

擴散節流

訊息擴散程序是指將訊息傳送至多部裝置的過程,例如您指定主題和群組,或是使用通知編輯器指定目標對像或使用者區隔。

訊息傳送作業不會立即發生,因此有時您同時進行多個擴散傳遞。每個專案的並行訊息傳送數量限制為 1,000 個。之後我們可能就會拒絕其他的擴散要求,或是延後要求的擴散傳遞,直到一些進行中的擴散傳遞作業完成。

實際的展開擴散率會受到同時要求展開傳送的專案數量影響。個別專案的 10,000 QPS 的展開率並不常見,但這個數字不保證一定是系統上的總負載。值得注意的是,可用的擴散容量會分配給各個專案,而非各個展開要求。因此,如果專案有兩個正在進行中的擴散傳遞作業,則每個擴散傳遞率只會看到一半可用的擴散傳遞率。如要盡可能提高展開速度,建議您一次只啟用一個展開擴散傳遞功能。

FCM 通訊埠和防火牆

如果貴機構的防火牆會將流量限制進出網際網路,您必須將其設為允許行動裝置與 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 分鐘以上的逾時時間。這有助於我們提供可靠的連線能力,同時減少使用者行動裝置的電池耗電量。

VPN 互動和可略過性

Firebase 雲端通訊會採取多個步驟,確保從手機到伺服器的推送訊息連線穩定且可供使用,而且盡可能頻繁。VPN 使用將使過程變得更加複雜。

VPN 會遮蓋 FCM 需要調整連線所需的基礎資訊,以盡可能提升可靠性和電池續航力。在某些情況下,VPN 會主動中斷長時間的有效連線,可能會因訊息遺失或延遲,或是電池成本高昂,而對使用者體驗造成負面影響。將 VPN 設定為允許執行時,我們會使用加密連線 (透過基本網路 Wi-Fi 或 LTE) 略過 VPN,以確保能提供穩定且電池便捷的體驗。FCM 對可略過的 VPN 的使用方式是 FCM 推播通知管道。其他 FCM 流量 (如註冊流量) 會使用 VPN (如果已啟用)。當 FCM 連線略過 VPN 時,會失去 VPN 提供的其他優勢,例如 IP 遮蓋。

不同的 VPN 有不同的方法,可控制是否可略過。如需操作說明,請參閱所用 VPN 的說明文件。

若未將 VPN 設為可略過,Firebase 雲端通訊會使用 VPN 網路來連線至伺服器。這可能會導致訊息延遲一段時間,而且由於雲端通訊會透過 VPN 連線保持連線,因此可能會導致耗電量增加。

憑證

視您實作的 FCM 功能而定,您可能需要從 Firebase 專案中取得下列憑證:

專案 ID Firebase 專案的專屬 ID,用於傳送至 FCM v1 HTTP 端點的要求。您可以在 Firebase 控制台的「設定」窗格中找到這個值。
註冊權杖

用來識別每個用戶端應用程式執行個體的專屬權杖字串。單一裝置和裝置群組訊息傳遞作業需要註冊權杖。請注意,註冊權杖不得對外公開。

傳送者 ID 建立 Firebase 專案時建立的專屬數值。可在 Firebase 控制台的「設定」窗格的「雲端通訊」分頁中找到。傳送者 ID 會用來識別可傳送訊息至用戶端應用程式的每位傳送者。
存取權杖 一個短期的 OAuth 2.0 權杖,用於授權對 HTTP v1 API 的要求。這項權杖已連結至屬於您 Firebase 專案的服務帳戶。如要建立及輪替存取權杖,請按照「 授權傳送要求」中所述的步驟操作。
伺服器金鑰 (適用於 **已淘汰** 舊版通訊協定)

這個伺服器金鑰可授權應用程式伺服器存取 Google 服務,包括透過已淘汰的 Firebase 雲端通訊舊版通訊協定傳送訊息。

重要事項:請勿在用戶端程式碼的任一處包含伺服器金鑰。此外,請確保僅使用伺服器金鑰授權應用程式伺服器。Android、Apple 平台和瀏覽器金鑰會遭到 FCM 拒絕。