Firebase Analytics

Firebase AnalyticsのデータをフラットなCSVに変換するETL処理

こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。

今日はFirebase Analyticsのデータについてです。

Firebase AnalyticsをBigQueryエクスポートすると、user_dimとevent_dimの2列だけのスキーマになりますよね。
Google Analyticsのデータもそうですが、JSONのようなネストになったレコードで構成されてます。

これらのネストになったデータを、サードパーティや自前のデータウェアハウスやデータベースにインポートしようとするなら、FLATTEN関数やUNNEST関数をつかってフラットな1行に展開して、つまりCSVデータに変換するようなETLを挟むと扱いやすくなります。

参考になるのは公式ブログですね。
BigQuery 活用術: UNNEST 関数
標準SQLのUNNEST関数を使う例。

あとは、レガシーSQLのFLATTEN関数を使う例もこちらのブログに載ってます。
Using BigQuery and Firebase Analytics to understand your mobile app

しかし私はどうもSQLじゃなくて他のプログラムで片付けるのが好みなので、Compute Engine上でNode.jsを使ってフラットなCSVデータに変換してみました。

 

BigQueryからJSON形式でCloud Storageにエクスポートする

まずはbqコマンドを使ってJSON型で抽出します。

$ bq extract --destination_format NEWLINE_DELIMITED_JSON foobar:firebasetest_ANDROID.app_events_20170702 gs://hoge/firebase/test20170702.json

 

Cloud StorageからCompute Engineにコピーする

次に、gsutilコマンドを使ってcompute engineのインスタンスにコピーします。

$ gsutil cp gs://hoge/firebase/test20170702.json ./

 

ネストされたJSONをフラットなCSVに変換

Node.jsで簡単なコードを書いて実行します。
JSONファイルをReadStreamで読み込みながら、ネストになったJSONレコードをフラットに1行にして、WriteStreamに書き出して行きます。

var fs = require("fs");
var rs = fs.createReadStream("test20170702.json");
var readline = require("readline");
var rl = readline.createInterface(rs, {});
var of = "test20170702.csv";
var ws = fs.createWriteStream(of, "utf-8");

rl.on("line", function(json) {
    var data = JSON.parse(json);

    //user_dimの展開
    var first_open_timestamp_micros = data.user_dim.first_open_timestamp_micros ? data.user_dim.first_open_timestamp_micros : "";
    var device_category = data.user_dim.device_info.device_category;
    var mobile_brand_name = data.user_dim.device_info.mobile_brand_name;
    var mobile_model_name = data.user_dim.device_info.mobile_model_name;
    var mobile_marketing_name = data.user_dim.device_info.mobile_marketing_name;
    var device_model = data.user_dim.device_info.device_model;
    var platform_version = data.user_dim.device_info.platform_version;
    var resettable_device_id = data.user_dim.device_info.resettable_device_id;
    var user_default_language = data.user_dim.device_info.user_default_language;
    var limited_ad_tracking = data.user_dim.device_info.limited_ad_tracking;
    var continent = data.user_dim.geo_info.continent;
    var country = data.user_dim.geo_info.country;
    var region = data.user_dim.geo_info.region;
    var city = data.user_dim.geo_info.city;
    var app_version = data.user_dim.app_info.app_version;
    var app_instance_id = data.user_dim.app_info.app_instance_id;
    var app_store = data.user_dim.app_info.app_store;
    var app_platform = data.user_dim.app_info.app_platform;
    var app_id = data.user_dim.app_info.app_id;
    var bundle_sequence_id = data.user_dim.bundle_info.bundle_sequence_id;
    
    //event_dimの展開
    for (var i = 0; i < data.event_dim.length; i++) {
        var date = data.event_dim[i].date;
        var event_name = data.event_dim[i].name;
        var timestamp_micros = data.event_dim[i].timestamp_micros;
        var firebase_screen = "";
        var firebase_screen_class = "";
        var engagement_time_msec = "";
        for (var j = 0; j < data.event_dim[i].params.length; j++) {
            if (data.event_dim[i].params[j].key == "firebase_screen") {
                firebase_screen = data.event_dim[i].params[j].value.string_value;
            } else if (data.event_dim[i].params[j].key == "firebase_screen_class") {
                firebase_screen_class = data.event_dim[i].params[j].value.string_value;
            } else if (data.event_dim[i].params[j].key == "engagement_time_msec") {
                engagement_time_msec = data.event_dim[i].params[j].value.int_value;
            }
        }
        ws.write(first_open_timestamp_micros + ",");
        ws.write(device_category + ",");
        ws.write(mobile_brand_name + ",");
        ws.write(mobile_model_name + ",");
        ws.write(mobile_marketing_name + ",");
        ws.write(device_model + ",");
        ws.write(platform_version + ",");
        ws.write(resettable_device_id + ",");
        ws.write(user_default_language + ",");
        ws.write(limited_ad_tracking + ",");
        ws.write(continent + ",");
        ws.write(country + ",");
        ws.write(region + ",");
        ws.write(city + ",");
        ws.write(app_version + ",");
        ws.write(app_instance_id + ",");
        ws.write(app_store + ",");
        ws.write(app_platform + ",");
        ws.write(app_id + ",");
        ws.write(bundle_sequence_id + ",");
        ws.write(date + ",");
        ws.write(event_name + ",");
        ws.write(timestamp_micros + ",");
        ws.write(firebase_screen + ",");
        ws.write(firebase_screen_class + ",");
        ws.write(engagement_time_msec + "\n");
    }
});

簡単なテストアプリのサンプルデータなので、カスタムのイベントとプロパティのデータの処理は入ってません。
なので実際はプロパティの数だけカラムは増えます。
あとはset_timestamp_usecやら、previous_timestamp_microsなど他にもデータはあるのですが、そこらへんは今回は省略してます。

このNode.jsを実行すると、このようなCSVデータになりました。

ネストされてないフラットなCSVなので、各データウェアハウスやデータベースに取り込みやすくなりました。

弊社ではFirebase Analyticsの他、Google AnalyticsやAdobe AnalyticsのデータをGoogle Cloud Platformを用いて分析する業務支援を行なっております。
お問い合わせはこちらからどうぞ。

ブログへの記事リクエストはこちらまで

ピックアップ記事

  1. 最速で理解したい人のためのIT用語集

関連記事

  1. ChatGPT

    ChatGPTとVSCodeの連携方法とその使用例:開発効率を飛躍的にアップさせる

    こんにちは、石原と申します。今回のブログが初投稿となります。…

  2. Application Integration

    Google Cloud iPaaS 「Application Integration」を使ってみた…

    こんにちは、エクスチュアの黒岩です。今回の記事では、Goog…

  3. Adobe Analytics

    Adobe Analytics: DWHレポートの日付列をBigQueryのDate型として扱う

    こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。…

  4. Databricks

    Databricks: Spark DataFramesをJDBCから作成する

    こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。…

  5. Google Cloud Platform

    【GCP】Cloud Workflowsでデータパイプラインの構築を試してみた②実践編

    こんにちは、エクスチュアの黒岩と申します。前回の記事では、G…

  6. Google Analytics

    Server-side GTMのGAビーコンログをBigQueryにエクスポートして分解する

    こんにちは、エクスチュアの権泳東(權泳東/コン・ヨンドン)です。…

最近の記事

  1. モダンデータスタックなワークフローオーケストレーションツール…
  2. Streamlit in Snowflakeによるダッシュボ…
  3. Streamlit in SnowflakeによるStrea…
  4. Streamlitを使った簡単なデータアプリケーション作成ガ…
  5. 生成AI機能を活かしたデータカタログ製品「Secoda」を試…
  1. Generative AI

    Snowflake の Copilot が優秀すぎる件について
  2. Google Tag Manager

    GTMでiframe内のクリックイベントを取得したい
  3. Adobe Analytics

    Adobe AnalyticsとGoogle Analyticsの違い② サンプ…
  4. Google Analytics

    Google Analyticsの「セグメント」機能について
  5. データサイエンス

    回帰分析はかく語りき Part2 重回帰分析
PAGE TOP