如要排解持續發生訊息傳送失敗的問題,請使用 FCM 疑難排解工具,並參閱這篇網誌文章,瞭解可能導致訊息無法顯示的各種原因。您也可以前往 FCM 狀態資訊主頁,確認是否有任何會影響 FCM 的服務中斷情形。
FCM 也提供三組工具,協助您深入評估訊息傳送成功率和策略:
- Firebase 控制台訊息傳送報告
- 透過 Firebase Cloud Messaging Data API 取得匯總的 Android SDK 傳送指標
- 將完整資料匯出至 Google BigQuery
BigQuery 資料匯出和 Firebase 控制台中的「報表」分頁需要 Google Analytics 才能運作。如果專案未啟用 Google Analytics,請前往 Firebase 專案設定的「整合」分頁進行設定。匯總運送資料不需要 Google Analytics 即可運作。
請注意,由於系統會批次處理分析資料,因此這個頁面上的許多統計資料最多可能會延遲 24 小時才顯示。
郵件傳送報告
在 Firebase 控制台的「報表」分頁中,您可以查看傳送至 Android 或 Apple 平台 FCM SDK 的訊息資料,包括透過通知撰寫工具和 FCM API 傳送的訊息:
- 已傳送 - 資料訊息或通知訊息已排入佇列,準備傳送,或已成功傳送至第三方服務 (例如 APNs)。請注意,傳送統計資料可能會延遲幾小時。 詳情請參閱訊息生命週期。
- 已接收 (僅適用於 Android 裝置):應用程式已收到資料訊息或通知訊息。接收端 Android 裝置必須安裝 FCM SDK 18.0.1 以上版本,才能取得這項資料。
- 曝光次數 (僅適用於 Android 裝置上的通知訊息) - 應用程式在背景執行時,裝置上已顯示通知。
- 開啟次數:使用者開啟通知訊息的次數。系統只會針對應用程式在背景執行時收到的通知回報。
這項資料適用於所有含有通知酬載的訊息,以及所有標示的資料訊息。如要進一步瞭解標籤,請參閱「在訊息中加入 Analytics 標籤」。
查看訊息報表時,您可以設定顯示資料的日期範圍,並選擇匯出為 CSV 檔案。你也可以依下列條件篩選:
- 平台 (iOS 或 Android)
- 應用程式
- 自訂 Analytics 標籤
在訊息中新增 Analytics 標籤
為郵件加上標籤非常適合用於自訂分析,方便您依標籤或標籤組合篩選傳送統計資料。如要為透過 HTTP v1 API 傳送的任何訊息新增標籤,請在訊息物件或平台專屬的 AndroidFcmOptions
或 ApnsFcmOptions
欄位中設定 fcmOptions.analyticsLabel
欄位。
數據分析標籤是 ^[a-zA-Z0-9-_.~%]{1,50}$
格式的文字字串。
標籤可包含大小寫字母、數字和下列符號:
-
~
%
長度上限為 50 個半形字元。每天最多可指定 100 個不重複的標籤; 如果郵件標籤超出上限,系統就不會回報。
在Firebase控制台訊息報表分頁中,您可以搜尋所有現有標籤的清單,並單獨或合併套用標籤,篩選顯示的統計資料。
使用 FCM Data API 取得匯總的放送資料
Firebase Cloud Messaging Data API 可讓您擷取資訊,瞭解以 Android 應用程式為目標的訊息要求結果。這個 API 會提供專案中所有已啟用資料收集功能的 Android 裝置匯總資料。包括訊息無延遲送達的百分比,以及在 Android 傳輸層中延遲或捨棄的訊息數量。評估這項資料可瞭解訊息傳送的整體趨勢,並協助您找出有效方法,提升傳送要求成效。如要瞭解報表中的可用日期範圍,請參閱匯總資料時間軸。
API 會提供特定應用程式的所有可用資料。請參閱 API 參考說明文件。
資料的細分方式為何?
遞送資料會依應用程式、日期和分析標籤細分。
呼叫 API 時,系統會傳回每個日期、應用程式和 Analytics 標籤組合的資料。舉例來說,單一 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 Cloud Messaging Data API 會提供 Android 傳輸層 (或 FCM 架構的步驟 3) 中發生的具體事件匯總詳細資料。這項資料可提供深入分析,瞭解 FCM 後端傳送訊息至 Android SDK 的情況。這項功能特別適合用來顯示郵件在傳輸期間延遲或遭到捨棄的趨勢。
在某些情況下,這兩組資料可能不會完全一致,原因如下:
- 匯總指標只會取樣部分郵件
- 匯總指標會四捨五入
- 我們不會顯示低於隱私權門檻的指標
- 由於我們對大量流量的管理方式進行最佳化,因此部分訊息結果會遺失。
API 的限制
匯總資料時間軸
API 會傳回 7 天的歷來資料,但透過這個 API 傳回的資料最多會延遲 5 天。舉例來說,1 月 20 日會提供 1 月 9 日至 1 月 15 日的資料,但不會提供 1 月 16 日之後的資料。此外,系統會盡力提供資料,如果發生資料中斷情形,FCM 會盡力修正問題,但不會在問題解決後回填資料。如果發生大規模中斷,資料可能無法使用一週以上。
資料涵蓋率
Firebase 雲端通訊資料 API 提供的指標,旨在深入瞭解訊息傳送的整體趨勢。不過,這些範本無法涵蓋所有訊息情境。下列情況是已知的結果,但不會反映在指標中。
過期的訊息
如果存留時間 (TTL) 在指定記錄日期結束後到期,系統就不會將該訊息計為當天的 droppedTtlExpired
。
傳送訊息到非使用中裝置
傳送至閒置裝置的訊息是否會顯示在資料集中,取決於訊息採用的資料路徑。這可能會導致 droppedDeviceInactive
和 pending
欄位出現誤算。
傳送訊息至符合特定使用者偏好設定的裝置
如果使用者在裝置上停用使用情況和診斷資訊的收集功能,系統就不會將他們的訊息納入計算,以符合使用者的偏好設定。
四捨五入和最低金額
如果數量不夠多,FCM 會刻意四捨五入並排除計數。
BigQuery 資料匯出
您可以將訊息資料匯出至 BigQuery,進行進一步分析。BigQuery 可讓您使用 BigQuery SQL 分析資料、將資料匯出至其他雲端供應商,或將資料用於自訂機器學習模型。匯出至 BigQuery 的資料包含所有可用的訊息資料,無論訊息類型為何,或訊息是透過 API 還是通知撰寫工具傳送。
如果訊息傳送至 SDK 最低版本為下列版本的裝置,您還可以選擇匯出應用程式的訊息傳送資料:FCM
- Android 20.1.0 以上版本。
- iOS 8.6.0 以上版本
- Firebase Web SDK 9.0.0 以上版本
如要瞭解如何為 Android 和 iOS 啟用資料匯出功能,請參閱下文。
如要開始使用,請將專案連結至 BigQuery:
選擇下列其中一種做法:
開啟通知撰寫工具,然後按一下頁面底部的「存取 BigQuery」。
在 Firebase 控制台的「整合」頁面中,按一下「BigQuery」資訊卡中的「連結」。
這個頁面會顯示專案中所有已啟用 FCM 的應用程式的 FCM 匯出選項。
按照畫面上的指示啟用 BigQuery。
詳情請參閱「將 Firebase 連結至 BigQuery」一文。
為 Cloud Messaging 啟用 BigQuery 匯出功能後:
Firebase 會將資料匯出至 BigQuery。請注意,資料匯出作業的初始傳播最多可能需要 48 小時才能完成。
- 您最多可以手動排定過去 30 天的資料補充作業。
建立資料集後,該資料集的位置就無法再變更,不過您可以將資料集複製到其他位置,或將資料集手動移動 (重新建立) 至其他位置。詳情請參閱「變更資料集位置」。
Firebase 會定期將資料從 Firebase 專案同步至 BigQuery。每日匯出作業會在太平洋時間凌晨 4 點開始,通常會在 24 小時內完成。
根據預設,您專案中所有的應用程式都會連結至 BigQuery,您之後才加進專案的應用程式也統統會自動與 BigQuery 連結。此外,您可以控管該讓哪些應用程式傳送資料。
如要停用「匯出」BigQuery功能,請在 Firebase 控制台中取消連結專案。
啟用訊息傳送資料匯出功能
搭載 FCM SDK 8.6.0 以上版本的 iOS 裝置,可以啟用應用程式的訊息傳送資料匯出功能。FCM 支援匯出快訊和背景通知的資料。 啟用這些選項前,請先按照「BigQuery 資料匯出」一文的說明,為專案建立 BigQuery 連結。FCM
啟用快訊通知的傳送資料匯出功能
只有快訊通知可以觸發通知服務應用程式擴充功能,因此您必須在應用程式中新增通知服務擴充功能,並在服務擴充功能內呼叫這個 API,才能啟用顯示訊息追蹤功能。請參閱 Apple 說明文件中的「修改新傳送通知中的內容」。
收到每則通知時,都必須發出下列呼叫:
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 | 伺服器記錄的事件時間戳記 |
project_number | INTEGER | 專案編號可識別傳送訊息的專案 |
message_id | STRING | 郵件 ID 可識別郵件。訊息 ID 是根據應用程式 ID 和時間戳記產生,在某些情況下可能不是全域專屬 ID。 |
instance_id | STRING | 郵件傳送對象應用程式的專屬 ID (如有)。可以是執行個體 ID 或 Firebase 安裝 ID。 |
message_type | STRING | 訊息類型。可以是通知訊息或資料訊息。主題:用於識別主題或廣告活動傳送的原始訊息;後續訊息為通知或資料訊息。 |
sdk_platform | STRING | 收件者應用程式的平台 |
app_name | STRING | Android 應用程式的套件名稱或 iOS 應用程式的軟體包 ID |
collapse_key | STRING | 摺疊鍵可識別可摺疊的訊息群組。如果裝置未連線,系統只會將具有指定摺疊鍵的最後一則訊息排入佇列,以便最終傳送 |
優先順序 | INTEGER | 訊息的優先順序。有效值為「normal」和「high」。在 iOS 中,這些優先順序分別對應至 APNs 優先順序 5 和 10 |
ttl | INTEGER | 這個參數會指定訊息應在 FCM 儲存空間保留多久 (以秒為單位),前提是裝置處於離線狀態 |
主題 | STRING | 訊息傳送至的主題名稱 (如適用) |
bulk_id | INTEGER | 大量 ID 可識別相關訊息群組,例如傳送至特定主題的訊息 |
事件 | STRING | 事件類型。
可能的值包括:
|
analytics_label | STRING | 使用 HTTP v1 API 時,您可以在傳送訊息時設定 Analytics 標籤,以便標記訊息以供 Analytics 使用 |
匯出資料的用途
以下各節提供查詢範例,您可以在 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;