BigQuery でエクスポートされたデータに対して SQL クエリを実行する

Crashlytics と(必要に応じて)Firebase セッション データを BigQuery にエクスポートしたら、データの操作を開始できます。

  • SQL クエリを使用してデータを分析する
    Crashlytics データに対してクエリを実行して、カスタム レポートと概要を生成できます。これらのタイプのカスタム レポートは Firebase コンソールの Crashlytics ダッシュボードでは利用できないため、クラッシュ データの分析と理解を補完できます。このページの後半で示すクエリの例をご覧ください。

  • 異なるデータセットのデータを結合する
    たとえば、Crashlytics データ エクスポートを設定するときに Firebase セッション データをエクスポートすることを選択すると、クラッシュの影響を受けていないユーザーとクラッシュが発生しなかったセッションをより詳しく理解できます(クエリの例を参照)。また、さまざまな Firebase プロダクト(Performance Monitoring など)や Google Analytics からデータをエクスポートし、BigQueryCrashlytics データと結合して分析することもできます。

  • ビューを作成する
    BigQuery UI を使用して、SQL クエリで定義した仮想テーブルである「ビュー」を作成できます。さまざまな種類のビューとその作成方法に関する詳細な手順については、BigQuery ドキュメントをご覧ください。

データセット スキーマの詳細については、BigQuery でエクスポートされたデータのデータセット スキーマをご覧ください。

BigQuery SQL について

Crashlytics データのクエリの例

このセクションでは、エクスポートした Crashlytics データと Firebase セッション データで BigQuery SQL を使用する方法を示す状況とクエリの例をいくつか紹介します。

例 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

過去 1 週間(過去 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: 日別のクラッシュ数を確認する

修正するバグがほとんどなくなり、チームは新しい写真共有アプリをリリース可能な状態になったと考えました。しかし、リリース前に、過去 1 か月間の 1 日あたりの障害件数を確認し、バグバッシュでアプリが時間とともに安定してきたことを確認したいと考えています。

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 アプリの早期アクセスを有効にしています。ほとんどのユーザーは問題なく利用していますが、3 人のユーザーから異常な数の障害件数が報告されました。根本的な原因を突き止めるため、これらのユーザーの 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: 特定のクラッシュ問題が発生しているすべてのユーザーを抽出する

チームが誤って、ベータ版テスターのグループに重大なバグをリリースしてしまいました。チームは、上記の「最も多いクラッシュを確認する」の例のクエリを使用して、クラッシュ問題の 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 を使用して 2 つのテーブルで共通するイベントの重複を排除できます。

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;

次のステップ