在 BigQuery 中對匯出的資料執行 SQL 查詢

Crashlytics 和 (選擇性) Firebase 工作階段資料匯出至 BigQuery 後,即可開始使用資料:

  • 使用 SQL 查詢分析資料
    您可以對 Crashlytics 資料執行查詢,產生自訂報表和摘要。由於這類自訂報表無法在 Firebase 控制台的 Crashlytics 資訊主頁中查看,因此可做為補充資料,協助您分析及瞭解當機資料。請參閱本頁稍後的查詢範例集合。

  • 合併不同資料集的資料
    舉例來說,如果您在設定資料匯出時選擇匯出 Firebase 工作階段資料,就能進一步瞭解未發生當機情形的使用者和工作階段 (請參閱範例查詢)。 Crashlytics此外,您也可以從各種 Firebase 產品 (例如 Performance Monitoring) 或 Google Analytics 匯出資料,然後在 BigQuery 中與 Crashlytics 資料合併及分析。

  • 建立檢視區塊
    使用 BigQuery UI 建立檢視區塊,也就是由 SQL 查詢定義的虛擬資料表。如需不同類型檢視區塊的詳細操作說明,以及如何建立檢視區塊,請參閱 BigQuery 說明文件

如要進一步瞭解資料集結構定義,請參閱「BigQuery 中匯出資料的資料集結構定義」。

瞭解 BigQuery SQL

Crashlytics 資料的查詢範例

本節提供一些範例情境和查詢,說明如何搭配使用 BigQuery SQL 與匯出的 Crashlytics 資料和 Firebase 工作階段資料。

範例 1:使用 Firebase 工作階段資料計算未發生當機情形的指標

您在最新版本中大幅改版應用程式,解決重要使用者歷程中的當機問題。您收到許多使用者好評,但希望取得量化證據,證明應用程式比以往更穩定。

未發生當機情形的指標可協助您取得這項資訊。這些指標是重要的評估標準,有助於瞭解應用程式的整體健康狀態。您可以使用基本查詢,透過 Firebase 工作階段資料和 Crashlytics 事件計算這些指標。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

特定版本的未受當機情況影響的使用者

SELECT
  TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date,
  (1 - (COUNT (DISTINCT installation_uuid) / COUNT (DISTINCT instance_id))) AS CFU
FROM
  `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions
LEFT JOIN
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics
ON
  TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY)
WHERE
  crashlytics.error_type="FATAL"
  AND crashlytics.application.display_version="APP_VERSION"
  AND sessions.application.display_version = "APP_VERSION"
GROUP BY
  event_date
ORDER BY
  event_date

過去一週 (過去 168 小時) 未發生當機情形的工作階段:

SELECT
  TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date,
  (1 - (COUNT (DISTINCT crashlytics.firebase_session_id) / COUNT (DISTINCT sessions.session_id))) AS CFS
FROM
  `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions
LEFT JOIN
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics
ON
  TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY)
WHERE
  crashlytics.error_type="FATAL" AND _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR)
  AND _PARTITIONTIME < CURRENT_TIMESTAMP()
GROUP BY
  event_date
ORDER BY
  event_date

範例 2:按天顯示的當機次數

在開發人員盡力排除各種錯誤後,您認為團隊終於可以推出新的相片分享應用程式。不過,您想先查看過去一個月內每天當機的次數,確認這段時間排除錯誤的確讓應用程式變得更穩定。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
  COUNT(DISTINCT event_id) AS number_of_crashes,
  FORMAT_TIMESTAMP("%F", event_timestamp) AS date_of_crashes
FROM
 `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
GROUP BY
  date_of_crashes
ORDER BY
  date_of_crashes DESC
LIMIT 30;

範例 3:找出最常發生的當機問題

為了適當排定生產計畫的優先順序,您想找出應用程式中最常出現的 10 大當機問題。因此您產生查詢,提供相關資料點。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
  DISTINCT issue_id,
  COUNT(DISTINCT event_id) AS number_of_crashes,
  COUNT(DISTINCT installation_uuid) AS number_of_impacted_user,
  blame_frame.file,
  blame_frame.line
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
  event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(),INTERVAL 168 HOUR)
  AND event_timestamp < CURRENT_TIMESTAMP()
GROUP BY
  issue_id,
  blame_frame.file,
  blame_frame.line
ORDER BY
  number_of_crashes DESC
LIMIT 10;

範例 4:前 10 大當機裝置

秋天是換新手機的季節!貴公司知道這也代表新手機問題特別多的季節來臨,尤其是 Android 手機。為了提早因應即將到來的相容性問題,您做了一個查詢,找出最近一週 (168 小時) 最常當機的 10 台裝置。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
  device.model,
COUNT(DISTINCT event_id) AS number_of_crashes
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
  event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR)
  AND event_timestamp < CURRENT_TIMESTAMP()
GROUP BY
  device.model
ORDER BY
  number_of_crashes DESC
LIMIT 10;

範例 5:依自訂鍵篩選

您是遊戲開發人員,想要瞭解遊戲的哪個關卡最常當機。

為協助追蹤這項統計資料,您設定了名為 current_level 的自訂 Crashlytics 鍵 (iOS+ | Android | Flutter | Unity ),並在使用者達到新等級時更新。

Swift

Crashlytics.sharedInstance().setIntValue(3, forKey: "current_level");

Objective-C

CrashlyticsKit setIntValue:3 forKey:@"current_level";

Java

Crashlytics.setInt("current_level", 3);

透過匯出至 BigQuery 中的這個鍵,您可以撰寫查詢,回報與每次當機事件相關聯的 current_level 值分佈情況。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
COUNT(DISTINCT event_id) AS num_of_crashes,
  value
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
UNNEST(custom_keys)
WHERE
  key = "current_level"
GROUP BY
  key,
  value
ORDER BY
  num_of_crashes DESC

範例 6:擷取使用者 ID

你擁有搶先體驗版 Android 應用程式。大部分使用者都對該應用程式感到滿意,但有三位使用者則遇到不尋常的當機次數。為了釐清問題的真正原因,您撰寫查詢,使用這些使用者的 ID 來提取所有當機事件。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT *
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
  user.id IN ("USER_ID_1", "USER_ID_2", "USER_ID_3")
ORDER BY
  user.id
 

範例 7:找出所有發生特定當機問題的使用者

您的團隊不慎將重大錯誤發布給一群 Beta 版測試人員。 您的團隊已使用上述「找出最普遍的當機問題」範例中的查詢,找出特定當機問題 ID。現在團隊想執行查詢,擷取受這項當機問題影響的應用程式使用者清單。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT user.id as user_id
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
  issue_id = "ISSUE_ID"
  AND application.display_version = "APP_VERSION"
  AND user.id != ""
ORDER BY
  user.id;

範例 8:按國家/地區劃分,受當機問題影響的使用者人數

您的團隊在推出新版本時發現重大錯誤,您可以使用上述「找出最普遍的當機問題」範例中的查詢,找出特定當機問題 ID。現在,您的團隊想瞭解這項當機問題是否已擴散到世界各地。

如要編寫這項查詢,團隊必須完成下列步驟:

  1. 啟用將 Google Analytics 資料匯出至 BigQuery 的功能。 請參閱「將專案資料匯出至 BigQuery」。

  2. 更新應用程式,將使用者 ID 傳遞至 Google Analytics SDK 和 Crashlytics SDK。

    Swift

    Crashlytics.sharedInstance().setUserIdentifier("123456789");
    Analytics.setUserID("123456789");
    

    Objective-C

    CrashlyticsKit setUserIdentifier:@"123456789";
    FIRAnalytics setUserID:@"12345678 9";
    

    Java

    Crashlytics.setUserIdentifier("123456789");
    mFirebaseAnalytics.setUserId("123456789");
    
  3. 撰寫查詢,使用使用者 ID 欄位,將 Google Analytics 資料集中的事件與 Crashlytics 資料集中的當機事件聯結。

    以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

    SELECT DISTINCT c.issue_id, a.geo.country, COUNT(DISTINCT c.user.id) as num_users_impacted
    FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` c
    INNER JOIN  `PROJECT_ID.analytics_TABLE_NAME.events_*` a on c.user.id = a.user_id
    WHERE
      c.issue_id = "ISSUE_ID"
      AND a._TABLE_SUFFIX BETWEEN '20190101'
      AND '20200101'
    GROUP BY
      c.issue_id,
      a.geo.country,
      c.user.id

範例 9:今天目前為止的前 5 大問題

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
  issue_id,
  COUNT(DISTINCT event_id) AS events
FROM
  `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME`
WHERE
  DATE(event_timestamp) = CURRENT_DATE()
GROUP BY
  issue_id
ORDER BY
  events DESC
LIMIT
  5;

範例 10:自「DATE」起的前 5 大問題,包括今天

您也可以使用縫合查詢合併批次和即時資料表,將即時資訊新增至可靠的批次資料。由於 event_id 是主鍵,因此您可以使用 DISTINCT event_id,從這兩個資料表中移除任何常見事件的重複項目。

以下是 Android 應用程式的查詢範例。如果是 iOS 應用程式,請使用軟體包 ID 和 IOS (而非套件名稱和 ANDROID)。

SELECT
  issue_id,
  COUNT(DISTINCT event_id) AS events
FROM (
  SELECT
    issue_id,
    event_id,
    event_timestamp
  FROM
    `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME`
  UNION ALL
  SELECT
    issue_id,
    event_id,
    event_timestamp
  FROM
    `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`)
WHERE
  event_timestamp >= PARSE_TIMESTAMP("%Y_%m_%d", "YYYY_MM_DD")
GROUP BY
  issue_id
ORDER BY
  events DESC
LIMIT
  5;

後續步驟