Check out what’s new from Firebase at Google I/O 2022. Learn more

了解消息傳遞

FCM 提供了三組工具來幫助您深入了解消息傳遞:

  • Firebase 控制台消息傳遞報告和通知漏斗分析
  • 來自 Firebase Cloud Messaging Data API 的匯總 Android SDK 交付指標
  • 全面的數據導出到 Google BigQuery

本頁中描述的報告工具​​都需要 Google Analytics 才能運行。如果您的項目未啟用 Google Analytics,您可以在 Firebase 項目設置的集成選項卡中進行設置。

請記住,由於分析數據的批處理,此頁面上的許多統計數據的報告可能會延遲長達 24 小時。

消息傳遞報告

在 Firebase 控制台的“報告”選項卡中,您可以查看發送到 Android 或 Apple 平台 FCM SDK 的消息的以下數據,包括通過 Notifications Composer 和 FCM API 發送的消息:

  • 發送 - 數據消息或通知消息已入隊以進行傳遞,或已成功傳遞到 APNs 等第三方服務以進行傳遞。有關更多信息,請參閱消息的生命週期
  • 已收到(僅適用於 Android 設備)— 應用程序已收到數據消息或通知消息。當接收 Android 設備安裝了 FCM SDK 18.0.1 或更高版本時,此數據可用。
  • 印像數(僅適用於 Android 設備上的通知消息)— 顯示通知已在應用程序處於後台時顯示在設備上。
  • 打開 — 用戶打開了通知消息。僅報告應用程序在後台時收到的通知。

此數據可用於所有帶有通知負載的消息和所有標記數據消息。要了解有關標籤的更多信息,請參閱向消息添加分析標籤

查看消息報告時,您可以設置顯示數據的日期範圍,並可選擇導出為 CSV。您還可以按以下條件過濾:

  • 平台(iOS 或 Android)
  • 應用程序
  • 自定義分析標籤

向消息添加分析標籤

標記消息對於自定義分析非常有用,允許您按標籤或標籤集過濾傳遞統計信息。您可以通過在消息對像或特定於平台的AndroidFcmOptionsApnsFcmOptions字段中設置fcmOptions.analyticsLabel字段,為通過 HTTP v1 API 發送的任何消息添加標籤。

Analytics 標籤是格式為^[a-zA-Z0-9-_.~%]{1,50}$的文本字符串。標籤可以包含大小寫字母、數字和以下符號:

  • -
  • ~
  • %

最大長度為 50 個字符。您每天最多可以指定 100 個唯一標籤;添加的標籤超出該限制的消息不會被報告。

在 Firebase 控制台消息報告選項卡中,您可以搜索所有現有標籤的列表,並單獨或組合應用它們以過濾顯示的統計信息。

通知漏斗分析

內置的通知漏斗分析顯示您的用戶如何響應從 Firebase 控制台發送的特定通知。此視圖包括以下類別的目標 iOS 和 Android 設備的數據:

  • 已發送通知 — 消息已入隊等待遞送或已成功傳遞給第三方服務(如 APNs)以進行遞送。請注意,針對過時的令牌或不活動的註冊可能會誇大這些統計數據。
  • 打開的通知 — 打開的通知數。僅報告應用程序在後台時收到的通知。
  • 觸發轉化事件的唯一身份用戶數(如果已定義)。

要查看通知漏斗分析:

  1. 在通知編輯器中,選擇通知選項卡。
  2. 單擊消息列表中已完成或正在進行的消息。顯示包含漏斗分析的擴展視圖。

Analytics 報告會定期更新,但在用戶打開通知和控制台中提供事件數據之間可能會有一些延遲。除了通知選項卡下的這些報告之外,您還可以在 Analytics 中構建自定義渠道,以可視化應用程序中一系列步驟的完成率。

通過 FCM 數據 API 聚合的交付數據

Firebase Cloud Messaging Data API 可讓您檢索有助於了解針對 Android 應用程序的消息請求結果的信息。 API 提供跨項目中所有支持數據收集的 Android 設備的聚合數據。這包括有關無延遲傳遞的消息百分比的詳細信息,以及在Android 傳輸層中延遲或丟棄的消息數量。評估這些數據可以揭示消息傳遞的廣泛趨勢,並幫助您找到提高發送請求性能的有效方法。

API 提供給定應用程序可用的所有數據。請參閱API 參考文檔

數據是如何分解的?

交付數據按應用程序、日期和分析標籤細分。對 API 的調用將返回日期、應用程序和分析標籤的每個組合的數據。例如,單個androidDeliveryData JSON 對像如下所示:

 {
  "appId": "1:23456789:android:a93a5mb1234efe56",
  "date": {
    "year": 2021,
    "month": 1,
    "day": 1
  },
  "analyticsLabel": "foo",
  "data": {
    "countMessagesAccepted": "314159",
    "messageOutcomePercents": {
      "delivered": 71,
      "pending": 15
    },
   "deliveryPerformancePercents": {
      "deliveredNoDelay": 45,
      "delayedDeviceOffline": 11
    }
  }

如何解釋指標

傳遞數據概述了符合以下每個指標的消息的百分比。一條消息可能適合多個指標。由於我們收集數據的方式以及我們聚合指標的粒度級別的限制,一些消息結果根本沒有在指標中表示,因此下面的百分比總和不會達到 100%。

計算接受的消息

數據集中包含的唯一計數是 FCM 接受以傳遞到 Android 設備的消息計數。所有百分比都使用該值作為分母。請記住,此計數不包括針對已在其設備上禁用收集使用情況和診斷信息的用戶的消息。

消息結果百分比

MessageOutcomePercents對像中包含的字段提供有關消息請求結果的信息。這些類別都是互斥的。它可以回答諸如“我的消息是否被傳遞?”之類的問題。和“是什麼導致消息被丟棄?”

例如, droppedTooManyPendingMessages字段的高值可能表明應用實例正在接收大量不可折疊的消息,超過 FCM 的 100 條待處理消息的限制。為了緩解這種情況,請確保您的應用處理對onDeletedMessages的調用,並考慮發送可折疊消息。同樣, droppedDeviceInactive的高百分比可能是更新服務器上的註冊令牌、刪除陳舊令牌並從主題中取消訂閱它們的信號。有關此領域的最佳實踐,請參閱管理 FCM 註冊令牌

交付績效百分比

DeliveryPerformancePercents對像中的字段提供有關已成功傳遞的消息的信息。它可以回答諸如“我的消息延遲了嗎?”之類的問題。和“為什麼消息延遲?”例如, delayedMessageThrottled的高值會清楚地表明您超出了每個設備的最大限制,並且應該調整您發送消息的速率。

消息洞察百分比

此對象提供有關所有消息發送的附加信息。 priorityLowered字段表示優先級從HIGH降低到NORMAL的已接受消息的百分比。如果此值較高,請嘗試發送較少的高優先級消息或確保在發送高優先級消息時始終顯示通知。有關更多信息,請參閱我們關於消息優先級的文檔

此數據與導出到 BigQuery 的數據有何不同?

BigQuery 導出提供有關 FCM 後端接受消息以及在設備上的 SDK 中傳遞消息的單獨消息日誌( FCM 架構的第 2 步和第 4 步)。此數據對於確保接受和傳遞單個消息很有用。在下一部分中詳細了解BigQuery 數據導出

相比之下,Firebase 雲消息傳遞數據 API 提供了有關在 Android 傳輸層(或FCM 架構的第 3 步)中具體發生的情況的匯總詳細信息。該數據專門提供了對從 FCM 後端到 Android SDK 的消息傳遞的洞察。它對於顯示在此傳輸過程中為什麼消息被延遲或丟棄的趨勢特別有用。

在某些情況下,由於以下原因,這兩個數據集可能不完全匹配:

  • 聚合指標僅對所有消息的一部分進行採樣
  • 匯總指標四捨五入
  • 我們不會提供低於隱私閾值的指標
  • 由於我們管理大量流量的方式進行了優化,部分消息結果丟失。

API 的限制

數據延遲

此 API 返回的數據最多會延遲 5 天。例如,在 1 月 10 日,1 月 5 日的數據可用,但 1 月 6 日或之後的數據不可用。此外,數據是盡最大努力提供的。如果發生數據中斷,FCM 將努力向前修復,並且在問題修復後不會回填數據。在較大的中斷中,數據可能會在一周或更長時間內不可用。

數據覆蓋率

Firebase Cloud Messaging Data API 提供的指標旨在深入了解消息傳遞的廣泛趨勢。但是,它們不能 100% 覆蓋所有消息場景。以下情景是未反映在指標中的已知結果。

折疊的消息

已被另一條消息折疊的消息不會出現在數據集中。

給非活動設備的消息

發送到非活動設備的消息可能會或可能不會顯示在數據集中,具體取決於它們採用的數據路徑。這可能會導致在droppedDeviceInactivepending字段中出現一些錯誤計數。

向具有特定用戶偏好的設備發送消息

根據他們的偏好,禁用收集其設備上的使用和診斷信息的用戶將不會將他們的消息包含在我們的計數中。

四捨五入和最小值

FCM 故意舍入並排除數量不夠大的計數。

BigQuery 數據導出

您可以將消息數據導出到BigQuery以進行進一步分析。 BigQuery 允許您使用 BigQuery SQL 分析數據,將其導出到另一個雲提供商,或將數據用於您的自定義 ML 模型。到 BigQuery 的導出包括消息的所有可用數據,無論消息類型如何,或者消息是通過 API 還是通過通知編寫器發送的。

對於發送到具有以下 FCM SDK 最低版本的設備的消息,您可以選擇為您的應用啟用消息傳遞數據的導出:

  • 安卓 20.1.0 或更高版本。
  • iOS 8.6.0 或更高版本
  • Firebase Web SDK 9.0.0 或更高版本

有關為AndroidiOS啟用數據導出的詳細信息,請參見下文。

首先,將您的項目鏈接到 BigQuery:

  1. 選擇以下選項之一:

    • 打開Notifications composer ,然後點擊頁面底部的訪問 BigQuery

    • 在 Firebase 控制台的集成頁面中,點擊BigQuery卡片中的鏈接

      此頁面顯示項目中所有啟用 FCM 的應用程序的 FCM 導出選項。

  2. 按照屏幕上的說明啟用 BigQuery。

如需了解詳情,請參閱將Firebase 鏈接到 BigQuery

當您為雲消息傳遞啟用 BigQuery 導出時:

  • Firebase將您的數據導出到 BigQuery。請注意,用於導出的數據的初始傳播最多可能需要 48 小時才能完成。

  • 創建數據集後,位置無法更改,但您可以將數據集複製到其他位置或手動將數據集移動(重新創建)到其他位置。要了解更多信息,請參閱更改數據集位置

  • Firebase 會定期將您的數據從 Firebase 項目同步到 BigQuery。這些每日出口操作從太平洋時間凌晨 4:00 開始,通常在 24 小時內完成。

  • 默認情況下,您項目中的所有應用都與 BigQuery 相關聯,您以後添加到項目中的所有應用都會自動與 BigQuery 相關聯。您可以管理哪些應用程序發送數據

要停用 BigQuery 導出,請在 Firebase 控制台中取消關聯您的項目

啟用消息傳遞數據導出

具有 FCM SDK 8.6.0 或更高版本的 iOS 設備可以啟用其應用的消息傳遞數據導出。 FCM 支持警報和後台通知的數據導出。在啟用這些選項之前,您必須首先為您的項目創建 FCM-BiqQuery 鏈接,如BigQuery 數據導出中所述。

啟用警報通知的交付數據導出

因為只有警報通知才能觸發通知服務應用擴展,所以您必須在應用中添加通知服務擴展,並在服務擴展中調用此 API 以啟用顯示消息跟踪。請參閱 Apple 關於修改新交付通知中的內容的文檔。

必須為收到的每個通知進行以下調用:

迅速

// For alert notifications, call the API inside the service extension:
class NotificationService: UNNotificationServiceExtension {
  override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
  Messaging.extensionHelper()
      .exportDeliveryMetricsToBigQuery(withMessageInfo:request.content.userInfo)
  }
}

Objective-C

// For alert notifications, call the API inside the service extension:
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
                   withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler {
  [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:request.content.userInfo];
}
@end

如果您使用 HTTP v1 API 構建發送請求,請確保在有效負載對像中指定mutable-content = 1

為後台通知啟用交付數據導出

對於應用在前台或後台時收到的後台消息,您可以在主應用的數據消息處理程序中調用數據導出 API。必須為收到的每個通知進行此調用:

迅速

// For background notifications, call the API inside the UIApplicationDelegate or NSApplicationDelegate method:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
  Messaging.extensionHelper().exportDeliveryMetricsToBigQuery(withMessageInfo:userInfo)
}

Objective-C

// For background notifications, call the API inside the UIApplicationDelegate or NSApplicationDelegate method:
@implementation AppDelegate
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  [[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}
@end

哪些數據會導出到 BigQuery?

請注意,針對過時的令牌或不活躍的註冊可能會誇大其中一些統計數據。

導出表的架構是:

_PARTITIONTIME時間戳此偽列包含加載數據的當天開始時間(以 UTC 為單位)的時間戳。對於 YYYYMMDD 分區,此偽列包含值 TIMESTAMP('YYYY-MM-DD')。
event_timestamp時間戳服務器記錄的事件時間戳
項目編號整數項目編號標識發送消息的項目
message_id細繩消息 ID 標識消息。從 App ID 和時間戳生成的消息 ID 在某些情況下可能不是全局唯一的。
instance_id細繩消息發送到的應用程序的唯一 ID(如果可用)。它可以是實例 ID 或 Firebase 安裝 ID。
消息類型細繩消息的類型。可以是通知消息或數據消息。主題用於標識主題或活動發送的原始消息;隨後的消息是通知或數據消息。
sdk_platform細繩收件人應用程序的平台
app_name細繩Android 應用程序的包名稱或 iOS 應用程序的包 ID
折疊鍵細繩折疊鍵標識一組可以折疊的消息。當設備未連接時,只有具有給定折疊鍵的最後一條消息排隊等待最終傳遞
優先事項整數消息的優先級。有效值為“正常”和“高”。在 iOS 上,這些對應於 APNs 優先級 5 和 10
ttl整數此參數指定如果設備處於脫機狀態,消息應在 FCM 存儲中保留多長時間(以秒為單位)
話題細繩向其發送消息的主題的名稱(如果適用)
bulk_id整數批量 ID 標識一組相關消息,例如發送到某個主題的特定消息
事件細繩事件的類型。可能的值為:
  • MESSAGE_ACCEPTED:消息被FCM服務器接收,請求有效;
  • MESSAGE_DELIVERED:消息已發送到設備上應用的 FCM SDK。默認情況下,不傳播此字段。要啟用,請按照setDeliveryMetricsExportToBigQuery(boolean)中提供的說明進行操作。
  • MISSING_REGISTRATIONS:由於缺少註冊,請求被拒絕;
  • UNAUTHORIZED_REGISTRATION:郵件被拒絕,因為發件人無權發送到註冊;
  • MESSAGE_RECEIVED_INTERNAL_ERROR:處理消息請求時出現未指明的錯誤;
  • MISMATCH_SENDER_ID:發送消息的請求被拒絕,因為發送消息的發送者 ID 與為端點聲明的 ID 不匹配;
  • QUOTA_EXCEEDED:發送消息的請求因配額不足而被拒絕;
  • INVALID_REGISTRATION:發送消息的請求因註冊無效而被拒絕;
  • INVALID_PACKAGE_NAME:由於包名無效,發送消息的請求被拒絕;
  • INVALID_APNS_CREDENTIAL:由於APNS證書無效,發送消息的請求被拒絕;
  • INVALID_PARAMETERS:發送消息的請求因參數無效而被拒絕;
  • PAYLOAD_TOO_LARGE:由於負載大於限制,發送消息的請求被拒絕;
  • AUTHENTICATION_ERROR:發送消息的請求由於身份驗證錯誤而被拒絕(檢查用於發送消息的 API Key);
  • INVALID_TTL:由於 TTL 無效,發送消息的請求被拒絕。
分析標籤細繩使用HTTP v1 API ,可以在發送消息時設置分析標籤,以便標記消息以用於分析目的

你可以用導出的數據做什麼?

以下部分提供了可以在 BigQuery 中針對導出的 FCM 數據運行的查詢示例。

按應用統計發送的消息

SELECT app_name, COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_id != ''
GROUP BY 1;

計算消息所針對的唯一應用程序實例

SELECT COUNT(DISTINCT instance_id)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED';

計算發送的通知消息

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_type = 'DISPLAY_NOTIFICATION';

統計發送的數據消息

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND message_type = 'DATA_MESSAGE';

計數發送到主題或活動的消息

SELECT COUNT(1)
FROM `project ID.firebase_messaging.data`
WHERE
  _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
  AND event = 'MESSAGE_ACCEPTED'
  AND bulk_id = your bulk id AND message_id != '';

要跟踪發送到特定主題的消息的事件,請修改此查詢以將AND message_id != ''替換為AND message_id = <your message id>; .

計算給定主題或活動的扇出持續時間

扇出開始時間是收到原始請求的時間,結束時間是創建針對單個實例的最後一條單獨消息的時間。

SELECT
  TIMESTAMP_DIFF(
    end_timestamp, start_timestamp, MILLISECOND
  ) AS fanout_duration_ms,
  end_timestamp,
  start_timestamp
FROM (
    SELECT MAX(event_timestamp) AS end_timestamp
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
      AND bulk_id = your bulk id
  ) sent
  CROSS JOIN (
    SELECT event_timestamp AS start_timestamp
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
      AND bulk_id = your bulk id
      AND message_type = 'TOPIC'
  ) initial_message;

已發送消息的計數百分比

SELECT
  messages_sent,
  messages_delivered,
  messages_delivered / messages_sent * 100 AS percent_delivered
FROM (
    SELECT COUNT(DISTINCT CONCAT(message_id, instance_id)) AS messages_sent
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND event = 'MESSAGE_ACCEPTED'
  ) sent
  CROSS JOIN (
    SELECT COUNT(DISTINCT CONCAT(message_id, instance_id)) AS messages_delivered
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND (event = 'MESSAGE_DELIVERED'
      AND message_id
      IN (
        SELECT message_id FROM `project ID.firebase_messaging.data`
        WHERE
          _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
          AND event = 'MESSAGE_ACCEPTED'
        GROUP BY 1
      )
  ) delivered;

跟踪給定消息 ID 和實例 ID 的所有事件

SELECT *
FROM `project ID.firebase_messaging.data`
WHERE
    _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
    AND message_id = 'your message id'
    AND instance_id = 'your instance id'
ORDER BY event_timestamp;

計算給定消息 ID 和實例 ID 的延遲

SELECT
  TIMESTAMP_DIFF(
    MAX(delivered_time), MIN(accepted_time), MILLISECOND
  ) AS latency_ms
FROM (
    SELECT event_timestamp AS accepted_time
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD')
      AND message_id = 'your message id'
      AND instance_id = 'your instance id'
      AND event = 'MESSAGE_ACCEPTED'
  ) sent
  CROSS JOIN (
    SELECT event_timestamp AS delivered_time
    FROM `project ID.firebase_messaging.data`
    WHERE
      _PARTITIONTIME = TIMESTAMP('date as YYYY-MM-DD') AND
      message_id = 'your message id' AND instance_id = 'your instance id'
      AND (event = 'MESSAGE_DELIVERED'
  ) delivered;