瞭解郵件傳送功能

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)
  • 應用程式
  • 自訂數據分析標籤

為訊息加入數據分析標籤

為訊息加上標籤非常適合用於自訂分析,可讓您依標籤或標籤集篩選傳送統計資料。您可以將標籤新增至透過 HTTP v1 API 傳送的任何訊息,方法是在訊息物件中設定 fcmOptions.analyticsLabel 欄位,或是在平台專屬的 AndroidFcmOptionsApnsFcmOptions 欄位中。

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

  • -
  • ~
  • %

長度上限為 50 個半形字元。您每天最多可以指定 100 個不重複標籤;如果郵件的標籤超出這個限制,則不會回報。

在 Firebase 控制台的訊息「報表」分頁中,您可以搜尋所有現有標籤的清單,然後單獨或組合這些標籤來篩選顯示的統計資料。

透過 FCM Data API 的匯總傳送資料

Firebase 雲端通訊資料 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 Export 會提供個別訊息記錄,說明 FCM 後端接受訊息的訊息,以及裝置上的 SDK 中傳遞的訊息 (FCM 架構的步驟 2 和 4)。這項資料有助於確保系統接受及傳送個別訊息。請參閱下一節,進一步瞭解 BigQuery 資料匯出

相反地,Firebase Cloud Messaging Data API 則提供 Android 傳輸層 (或 FCM 架構步驟 3) 中具體情況的匯總詳細資料。這項資料特別可讓您深入瞭解從 FCM 後端將訊息傳送至 Android SDK。如果您想瞭解郵件在傳輸過程中遭到延遲或捨棄的原因,這項功能尤其實用。

在某些情況下,導致兩個資料集可能無法精確比對,可能的原因如下:

  • 匯總指標只會對部分訊息的一部分進行取樣
  • 匯總指標會四捨五入
  • 我們不會顯示低於隱私權門檻的指標
  • 在處理大量流量的最佳化方式下,部分訊息結果遺漏。

API 的限制

匯總資料時間軸

API 會傳回 7 天的歷來資料,但這個 API 傳回的資料最多會延遲 5 天。舉例來說,系統會在 1 月 20 日提供 1 月 9 日至 15 日的資料,但無法提供 1 月 16 日以後的資料。除此之外,我們也會盡可能提供資料。如果發生資料中斷事件,FCM 會著手修正,不會在問題解決後補充資料。在較大的服務中斷中,資料可能會無法使用一週或更長的時間。

資料涵蓋率

Firebase Cloud Messaging Data API 提供的指標旨在深入分析各種訊息傳送趨勢。但無法為所有訊息情境提供 100% 的涵蓋率。下列情境是指標並未反映的已知結果。

過期訊息

如果存留時間 (TTL) 在指定記錄日期結束後到期,訊息在這個日期將不會計為 droppedTtlExpired

傳送訊息給閒置裝置

傳送至閒置裝置的訊息不一定會顯示在資料集中,視裝置採用的資料路徑而定。這可能會導致 droppedDeviceInactivepending 欄位中的計數有誤。

傳送訊息給符合特定使用者偏好設定的裝置

如果使用者停用了裝置上的使用狀況與診斷資訊收集功能,他們的訊息就不會納入計算,而是依照使用者的偏好設定計算。

捨入與下限

FCM 會刻意無條件捨去,而在磁碟區不夠大時,則會排除計數。

BigQuery 資料匯出

您可以將訊息資料匯出至 BigQuery,以便進一步分析。BigQuery 可讓您使用 BigQuery SQL 分析資料、匯出至其他雲端服務供應商,或將資料用於自訂機器學習模型。無論訊息類型為何,或訊息是透過 API 或通知編輯器傳送,匯出至 BigQuery 都會包含所有訊息可用資料。

如果訊息會傳送至符合下列 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 一文。

為雲端通訊啟用 BigQuery Export 功能後:

  • Firebase 會將資料匯出至 BigQuery。請注意,資料首次的匯出作業最多可能需要 48 小時才能完成。

  • 建立資料集後,該資料集的位置就無法再變更,不過您可以將資料集複製到其他位置,或是在其他位置手動移動 (重新建立) 資料集。詳情請參閱變更資料集位置

  • Firebase 會設定將 Firebase 專案中的資料定期同步至 BigQuery。這些每日匯出作業會在太平洋時間凌晨 4 點開始,通常會在 24 小時內完成。

  • 根據預設,專案中的所有應用程式都會連結至 BigQuery,而您之後新增至專案的所有應用程式都會自動連結至 BigQuery。此外,您可以管理該讓哪些應用程式傳送資料

如要停用 BigQuery 匯出功能,請在 Firebase 控制台中取消連結專案

啟用郵件傳送資料匯出功能

搭載 FCM SDK 8.6.0 以上版本的 iOS 裝置可以啟用應用程式的訊息傳送資料匯出功能。FCM 支援匯出快訊和背景通知的資料。啟用這些選項之前,您必須先按照 BigQuery 資料匯出中所述,為專案建立 FCM-BiqQuery 連結。

啟用快訊通知的傳送資料匯出功能

由於只有快訊通知可以觸發通知服務應用程式額外資訊,因此您必須在應用程式中新增通知服務擴充功能,並在服務擴充功能中呼叫這個 API,才能啟用顯示訊息追蹤功能。請參閱 Apple 說明文件的「在 Newly Delivered Notifications 中修改內容」。

每次收到通知時,都必須發出以下呼叫:

Swift

// 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。每次收到通知時都必須發出這項呼叫:

Swift

// 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 TIMESTAMP 這個虛擬資料欄包含資料載入當天開始 (世界標準時間) 的時間戳記。如果是 YYYYMMDD 分區,這個虛擬資料欄含有 TIMESTAMP('YYYY-MM-DD' 的值)。
event_timestamp TIMESTAMP 伺服器記錄的事件時間戳記
專案編號 INTEGER 專案編號可識別傳送訊息的專案
message_id STRING 郵件 ID 可用於識別郵件。由應用程式 ID 和時間戳記產生,訊息 ID 在某些情況下可能不俱全域唯一性。
instance_id STRING 接收訊息的應用程式專屬 ID (如果有的話)。可以是執行個體 ID 或 Firebase 安裝 ID。
message_type STRING 訊息的類型。可以是通知訊息或資料訊息。主題可用來識別主題或廣告活動傳送的原始訊息;後續訊息為通知或資料訊息。
sdk_platform STRING 接收者應用程式的平台
應用程式名稱 STRING Android 應用程式的套件名稱,或 iOS 應用程式的軟體包 ID
收合鍵 STRING 收合鍵可識別可收合的一組訊息。如果裝置未連線,系統只會將含有指定收合鍵的最後一則訊息排入佇列,以此進行最終傳送
優先順序 INTEGER 訊息的優先順序。有效值為「normal」和「高」。在 iOS 上,這些會對應至 APN 優先順序 5 和 10
文字轉語音 INTEGER 此參數用於指定裝置離線時,訊息應保留在 FCM 儲存空間中的時間長度 (以秒為單位)
主題 STRING 傳送訊息的主題名稱 (如適用)
大量 ID INTEGER 大量 ID 可識別一組相關訊息,例如傳送給主題的特定訊息
事件 STRING 事件的類型。 可能的值包括:
  • 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 金鑰)。
  • INVALID_TTL:傳送訊息的要求因存留時間無效而遭到拒絕。
Analytics (分析) 標籤 STRING 如果使用 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 = <your message id>; 取代 AND 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;