この記事は [author] による The Firebase Blog の記事 "How do I add Firebase Analytics to an app that's already using Google Analytics?" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。


Todd Kerpleman



Todd Kerpelman
Developer Advocate
私たちがよく遭遇するシナリオがあります。Firebase Analytics を使ってアプリ内のイベントデータのトラッキングや把握を行いたいものの、今まで何年もかけて Google アナリティクスの実装の微調整やチューニングを行ってきたため、新しいレポーティング ツールを白紙から使い始めるのは気が進まないという状況です。

それでも、Firebase Analytics やそれが提供する横断的機能の活用には興味があります。たとえば、自分で定義できるユーザー層(Audience)を作成して通知の対象を絞り込む機能や、Remote Config の対象指定に利用できるユーザー プロパティを作成する機能などです。

では、どうすれば両方を同時に使うことができるでしょうか。ここでは、Firebase Analytics を Google アナリティクス対応アプリに追加したい方向けに、いくつかの戦略を紹介しましょう。

まずはイベントについての話から
もう少し具体的な例をあげましょう。モバイルゲームがあり、ラウンドが終わるたびにいくつかのイベントを Google アナリティクスに送信する場合を考えます。具体的には、合計スコア、倒した敵の数、生き延びたラウンド数の 3 つです。これらの値を Google アナリティクスに記録する方法は次のようになります。
func recordGameOver() {
    let tracker = GAI.sharedInstance().defaultTracker
    let gameOverEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver",
       action: "totalScore", 
       label: "", 
       value: myGameStats.totalScore as NSNumber)
    let enemiesBeatenEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver",
       action: "enemiesBeaten", 
       label: "", 
       value: myGameStats.enemiesBeaten as NSNumber)
    let roundsSurvivedEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver", 
       action: "roundsSurvived", 
       label: "", 
       value: myGameStats.roundsSurvived as NSNumber)
    tracker?.send(gameOverEvent.build() as [NSObject: AnyObject])
    tracker?.send(enemiesBeatenEvent.build() as [NSObject: AnyObject])
    tracker?.send(roundsSurvivedEvent.build() as [NSObject: AnyObject])
}

お気づきの方もいらっしゃるかもしれませんが、カスタム ディメンションを持つ 1 つのイベントを使っても同じことを行えます。大まかな考え方は同じで、これだけを行いたいのであれば、ひょっとすると 1 つのイベントを使う方が簡単かもしれません。

この仕組みによって、Google アナリティクスでちょっとしたすばらしいレポートができ、やがてはプレイヤーの最終スコア、倒した敵の数、生き残ったラウンド数を確認できるようになります。

では、どうすればこれを Firebase Analytics イベントに変換できるかを考えてみましょう。Google アナリティクスは 1 つのイベントに 1 つの値が関連付けられる階層構造になっています。一方、Firebase Analytics では 1 つのイベントに複数のキーと値のペアをイベント パラメータとして渡すことができます。

そのため、Google アナリティクス イベントから Firebase Analytics イベントへの変換は、非常に単純な 1 対 1 の変換として実行できます。次の例をご覧ください。

  FIRAnalytics.logEvent(withName: "gameOverTotalScore", 
      parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
  FIRAnalytics.logEvent(withName: "gameOverEnemiesBeaten", 
      parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
  FIRAnalytics.logEvent(withName: "gameOverTotalScore", 
      parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
しかし、Firebase Analytics の世界では、次のようにして複数のカスタム パラメータを持つ 1 つのイベントとして記録する方が自然です。
  let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
                    "enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
                    "roundsSurvived": myGameStats.roundsSurvived as NSObject]
  FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)

(カスタム ディメンションによるアプローチを取ろうとした方は、これに近いものになっているはずです)

この 2 番目のアプローチを取るというと、BigQuery を使ってイベントとともに送信されたカスタム パラメータを分析する必要があります。しかし、実のところ、アナリティクス データを本気で気にしている方が探しているのはこのようなものでしょう。幸運なことに、このことを説明した動画もすでにあります。

正しい方法で Firebase を追加する
Firebase Analytics を動作させようとする際に最初にぶつかる壁の 1 つは、似たようなセットアップ プロセスが Google アナリティクスと Firebase Analytics の両方で使われていることです。

たとえば iOS では、多くのデベロッパーが Google アナリティクスを動作させるために GoogleService-info.plist ファイルを生成して Xcode プロジェクトに追加しています。しかし、Firebase Analytics を正しく設定するには、もう 1 つの GoogleService-info.plist ファイルを生成してそれを Xcode プロジェクトに追加しなければなりません。どうすればこの両方を行えるでしょうか。

ここでの答えは、Firebase をインストールする際に、コンソールで新しい Firebase プロジェクトを作るのではなく、Google アナリティクス対応の既存プロジェクトを Firebase にインポートすることです。

これを行うには、Firebase プロジェクトを作成する際に、[Import Google Project] ボタンをクリックします。そして、Google アナリティクス対応プロジェクトを選択してから、プロジェクト設定の GoogleService-info ファイルをダウンロードし直します。

これによって得られるのは、Firebase Analytics と Google アナリティクスのそれぞれから入手できる plist ファイルの両方を含んだものになります。ファイルの中身を調べれば、Google アナリティクスのトラッキング ID と一致する TRACKING_ID のエントリとともに、Firebase に関するさまざまな情報が追加されていることがわかるでしょう。古い GoogleService-info ファイルをこの新しいファイルで置き換えて、残りの Firebase インストール プロセスを終えれば、準備完了です。

Android での手順も基本的には同じです。ただし、.plist ファイルではなく、.json ファイルを使います。おそらく、Xcode ではなく Android Studio を使うことになるでしょう。

では、プロジェクトの設定が正しくできたとして、どうすれば Google アナリティクスと Firebase Analytics の両方にデータを含めることができるようになるでしょうか。それには、3 つの方法が考えられます。

オプション 1: 単純に 2 つの Analytics SDK を利用する
もっとも単純なシナリオは、そのまま Google アナリティクス サービスを利用しつつ、アプリをトラッキングする Firebase Analytics を追加することです。その場合、クライアントのコードは次のようになります。

func recordGameOver() {
    // All the old code you had previously to record Google Analytics
    // … 
    // … So much code … 
    // … 
    // Now add the Firebase stuff
    let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
                      "enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
                      "roundsSurvived": myGameStats.roundsSurvived as NSObject]
    FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
}

デベロッパーの観点から見れば、なぜこのソリューションが魅力的かわかるでしょう。とても簡単に実装でき、リスクもほとんどありません。現在の Google アナリティクス レポートに問題が起きることを心配する必要もありません。すべてのクライアント コードはそのままであり、今までとまったく同じように Google アナリティクスを呼び出しているからです。新しいコードでは、Firebase Analytics も呼び出してそちらにもデータを渡しているだけです。
しかし、このソリューションにはいくつかの欠点があります。まず、データを 2 種類のアナリティクス パッケージに送っている点です。一般的に、これはクライアントが今までよりも多くのネットワーク呼び出しを行っていることを意味します。したがって、アプリは今まで以上にユーザーのモバイルデータを使うことになり、電池も悪影響を受けます。ただし、Firebase Analytics はネットワークの呼び出しがかなり控えめであるため、Google アナリティクスのトラフィックにわずかに上乗せされる程度かもしれません。

おそらく、それよりも大きな欠点は、あらゆる場所でアナリティクスのコードが 2 重に書かかれることです。すでにアナリティクスの呼び出しを別のメソッドに抽象化しているなら、実装の詳細を隠すことができるので、これはさほど大きな問題ではないかもしれません。そのメソッド 1 つに Firebase を追加すれば済むでしょう。しかし、そうでない場合、アプリ全体にこのコードを追加するというのはさほど魅力的だとは思わないでしょう。そんな方のために、別のオプションも用意されています。

オプション 2: Google タグマネージャを使用して両方にイベントを報告する

Google タグマネージャはスイスアーミーナイフのような万能ツールで、いつも私の「いつかじっくり学びたいもの」リストに載っています。これには、正当な理由があります。Google タグマネージャの非常によくできた機能の 1 つは、送信される Firebase Analytics イベントを検知すると、同じイベントを Google アナリティクスやサードパーティ アナリティクス プロバイダにも送信してくれることです。
このソリューションが優れているのは、クライアントに必要なアナリティクス用のレポーティング コードは 1 セットのみであるという点です。この例では、Google アナリティクスの呼び出しを完全に削除でき、はるかに単純な実装が可能です。

func recordGameOver() {
    let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
                      "enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
                      "roundsSurvived": myGameStats.roundsSurvived as NSObject]
    FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
    // That's it!
}

Google タグマネージャを使ってこれらのイベントを Google アナリティクスに報告するには、CocoaPods または Gradle からライブラリをインストールし、プロジェクトに .json ファイルを追加する必要があります。クライアント側での作業はこれで完了です。ほとんどの作業は、タグマネージャのコンソールで行います。

タグマネージャのコンソールで、Google アナリティクスに送信したいすべての値について、Firebase イベント パラメータ変数を作成します。この例では、totalScore、enemiesBeaten、roundsSurvived の値が必要です。

次に、それぞれの Firebase Analytics イベントに対応するトリガーを作成します。今回の場合は、「gameOver」という名前のイベントが発生したときに作動するトリガーを作成します。

最後に、このトリガーに反応して Google アナリティクスにイベントを送信するタグを作成します(これは、Google タグマネージャ内ではユニバーサル アナリティクスと呼ばれています)。AppsFlyer、Kochava、Tune などのサービスにイベントを送信することもできます。

正直なところ、私がこのアプローチを気に入っている理由は、通常、コードを書く量が少なくて済むことはよいことだからです。また、このアプローチには、アプリをリリースした後であっても特定のイベントを Google アナリティクスだけに(または Firebase Analytics だけに)レポートしたり、Firebase Analytics イベントを Google アナリティクスにレポートする方法を変更できるといった柔軟性があります。
ここで 1 つ重要になることは、現在のところ、Firebase Analytics と Google タグマネージャを一緒に使って e コマースのデータを Google アナリティクスに送ることはできない点です。現在、この件についての対応が進められていますが、Google アナリティクスで e コマースのデータが必要な場合、しばらくの間は、他のオプションの利用を検討するか、e コマース イベントを直接 Google アナリティクスに送信するコードをそのまま残しておく必要があります。

しかし、先ほどと同じように、このオプションでもクライアントからのアナリティクスの呼び出しは 2 重に行われています。これはよいこととは言えません。また、多くの時間をかけて、Google タグマネージャ パネルからトリガー、イベント、タグをすべて事前に追加しておく必要もあります。とはいえ、その程度で済むならよい方でしょう。
しかし、クライアントで 2 つのアナリティクス SDK を実行したくない場合はどうでしょう。他に考えられるオプションはあるでしょうか。もちろんです。

オプション 3: BigQuery を使ってすべてを結合する

もう 1 つの考えられるオプションは、クライアントの Google アナリティクスを完全に Firebase Analytics で置き換え、バックエンドで BigQuery を使って古い Google アナリティクス データと新しい Firebase Analytics データを結合することです。


実際にこのソリューションが意味を持つのは、すでに Google アナリティクス 360 ユーザーであり、現在大半のカスタム レポートに BigQuery を使っている場合のみでしょう。そのような場合は、両方のデータソースからデータを取得するように BigQuery クエリをアップデートするのが妥当なオプションかもしれません。

今回の例に戻り、BigQuery で次のようなクエリを実行して「最終スコアの日別の平均」レポートの生成がすでに行われているとします。

SELECT
  AVG(hit.eventInfo.eventValue)
FROM
  `my_awesome_app.ga_sessions_20170123`,
  UNNEST(hits) AS hit
WHERE
  hit.eventInfo.eventCategory = "gameOver"
  AND hit.eventInfo.eventAction = "totalScore"
これを Firebase Analytics に切り替えます。クライアント側では、Firebase Analytics のみを呼び出す先ほどの例の単純な実装を使用します。
func recordGameOver() {
    let finalStats = ["totalScore": myGameStats.totalScore as NSObject,
                      "enemiesBeaten": myGameStats.enemiesBeaten as NSObject,
                      "roundsSurvived": myGameStats.roundsSurvived as NSObject]
    FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
    // That's it!
}
時間ごとに倒した敵の数の平均を確認したい場合、2 つのデータセットを結合する必要があります。この SQL は、次のようなものになります。

SELECT
  COUNT(*),
  AVG(total_score) AS average
FROM (
  SELECT
    event_param.value.int_value AS total_score
  FROM
    `firebase-project.com_example_awesome_app.app_events_20170123`,
    UNNEST(event_dim) AS event,
    UNNEST(event.params) AS event_param
  WHERE
    event.name = "gameOver"
    AND event_param.key = "totalScore"
  UNION ALL
  SELECT
    hit.eventInfo.eventValue AS total_score
  FROM
    `my_awesome_app.ga_sessions_20170123`,
    UNNEST(hits) AS hit
  WHERE
    hit.eventInfo.eventCategory = "gameOver"
    AND hit.eventInfo.eventAction = "totalScore" )

明らかに、これはとても単純な例です。やりたいことやデータの構造によっては、急激に複雑になることも考えられます。しかし、もう少し洗練されたクエリを紹介してくれるGoogle クラウド ビッグデータ ブログに投稿している(もっと優秀な)同僚もいます。こちらにもぜひご注目ください。
いかがでしたでしょうか。今回は、すでに Google アナリティクス用に設定されているアプリに Firebase Analytics を追加する方法について、いくつかのヒントを紹介いたしました(この方法はその他のアナリティクス プラットフォームでも応用できます)。設定を終えたら、特定のプロパティを持つユーザーに新しい Remote Config 設定を提供する機能や、作成した Firebase Analytics オーディエンスに通知を送る機能など、Firebase Analytics データを利用するいくつかの Firebase 機能を試してみることをお勧めします。そして、Firebase Analytics でトラッキングするイベントを増やしてみてください。Firebase Analytics は無料で制限なく利用できます。アプリにどれほどのユーザーがいても大丈夫です。今後 1 年間で、Firebase Analytics にはさらに多くのおもしろいツールや機能が追加される予定です。モバイルアプリに Firebase Analytics を追加するのに早すぎるということはありません。ぜひお試しください。

Posted by Khanh LeViet - Developer Relations Team