了解消息傳遞

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

  • Firebase 控制台消息傳遞報告
  • 來自 Firebase Cloud Messaging Data API 的聚合 Android SDK 交付指標
  • 全面的數據導出至 Google BigQuery

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

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

消息傳遞報告

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

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

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

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

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

向消息添加分析標籤

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

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

  • -
  • ~
  • %

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

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

通過 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將返回7天的歷史數據;但是,該API返回的數據最多會延遲5天。例如,1 月 20 日,1 月 9 日至 1 月 15 日的數據可用,但 1 月 16 日及之後的數據不可用。此外,數據是盡最大努力提供的。如果發生數據中斷,FCM 將努力向前修復,問題修復後不會回填數據。在較大的中斷中,數據可能會在一周或更長時間內不可用。

數據覆蓋範圍

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

折疊的消息

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

發送至非活動設備的消息

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

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

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

四捨五入和最小值

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

BigQuery 數據導出

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

對於發送到具有以下 FCM SDK 最低版本的設備的消息,您可以使用附加選項來啟用應用程序的消息傳送數據導出:

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

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

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

  1. 選擇以下選項之一:

    • 打開通知編輯器,然後點擊頁面底部的訪問 BigQuery

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

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

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

有關詳細信息,請參閱將 Firebase 鏈接到 BigQuery

當您為 Cloud Messaging 啟用 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?

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

導出表的schema為:

_PARTITIONTIME時間戳此偽列包含加載數據的當天開始的時間戳(以 UTC 為單位)。對於 YYYYMMDD 分區,此偽列包含值 TIMESTAMP('YYYY-MM-DD')。
事件時間戳時間戳服務器記錄的事件時間戳
項目編號整數項目編號標識發送消息的項目
消息ID細繩消息ID標識消息。消息 ID 由應用程序 ID 和時間戳生成,在某些情況下可能不是全局唯一的。
實例 ID細繩消息發送到的應用程序的唯一 ID(如果可用)。它可以是實例 ID 或 Firebase 安裝 ID。
消息類型細繩消息的類型。可以是通知消息或數據消息。主題用於識別主題或活動發送的原始消息;後續消息是通知消息或數據消息。
sdk_平台細繩接收者應用程序的平台
應用程序名稱細繩Android 應用程序的包名稱或 iOS 應用程序的捆綁包 ID
折疊鍵細繩折疊鍵標識一組可以折疊的消息。當設備未連接時,只有具有給定折疊鍵的最後一條消息才會排隊等待最終傳遞
優先事項整數消息的優先級。有效值為“正常”和“高”。在 iOS 上,這些對應於 APN 優先級 5 和 10
TTL整數此參數指定如果設備離線,消息應在 FCM 存儲中保留多長時間(以秒為單位)
話題細繩消息發送到的主題的名稱(如果適用)
批量 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;