Firebase向けGoogle Analytics [仕組みと活用例]

[ACCESS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/access) 15日目の記事になります。

# はじめに

[Firebase向けGoogle Analytics](https://firebase.google.com/products/analytics?hl=ja) (Google Analytics for Firebase)はモバイル、Webアプリ向けのログ解析サービスです。
以前はFirebase Analyticsという名前でした。
本記事ではモバイル(iOS / Android)向けのログ収集について取り上げます。

# どのようなことが分析できるか

- どの画面がどれぐらい表示されるか (表示時間、割合)
- ある画面操作をユーザー属性別に統計を取る
- ある機能がどの程度利用されているか (操作回数、使用時間)
- ある画面にたどり着くルートのうちどちらが多いか

# 仕組み

iOSはCocoapods、AndroidはGradleでライブラリが提供されています。
ライブラリを使ってユーザーの属性やイベントと呼ばれるユーザー操作などのログを送信するように実装します。

詳しくは[Firebaseのドキュメント](https://firebase.google.com/docs/analytics)に記載されています。

## Firebase Console

収集したデータを閲覧するサービスです。
どのような画面かは[デモプロジェクト](https://console.firebase.google.com/u/0/project/fir-demo-project/overview?hl=ja)をみると雰囲気が分かります。 (Googleアカウントが必要)
iOS, Androidのアプリの両方を同じプロジェクトで管理することができます。

## [イベント](https://firebase.google.com/docs/analytics/events)

ユーザーの操作などをイベントという形で記録できます。

例えば`screen_view`は画面が移り変わったときに記録されます。これはライブラリを導入しただけで収集されるイベントの1つです。
cf. [自動的に収集されるイベント](https://support.google.com/firebase/answer/6317485)
これはユーザーが表示した全ての画面が記録されるので、アプリの中でどの画面が最も多く表示されているかというのも分かります。

[デモプロジェクトのscreen_view](https://console.firebase.google.com/u/0/project/fir-demo-project/analytics/app/android:com.labpixies.flood/events/~2Freport~2Fscreen_view%3Ft%3D1607859438085&fpn%3D300830567303&swu%3D1&sgu%3D1&sus%3Dupgraded&params%3D_u..pageSize%253D25%2526_r..eventId%253Dscreen_view%2526_u..dataFilters%253Dplatform%252Candroid%252CEQ%252CDIMENSION%252C%252C&cs%3Dapp.m.events.detail&r%3Dscreen_view&g%3D1?hl=ja)を見ると`ユーザーエンゲージメント`の枠に画面の名前が表示されています。
iOSならViewController、AndroidならActivityがデフォルトで収集されます。
エンゲージメント率が高いと多く表示されているということになります。

### カスタムイベント

任意のタイミングでイベントを送信するには次のように書きます。(Android・Kotlinの場合)

```kotlin:Kotlin
import com.google.firebase.analytics.FirebaseAnalytics

FirebaseAnalytics.getInstance(context).logEvent("tweet") {
    param("text_length", length)
    param("images", count)
}
```

paramというのはカスタムパラメータで、key-value形式で設定できます。
ただしパラメータの数は25個まで、key nameは40文字以内、英数字+アンダースコア`_`のみという制約があるので注意が必要です。

- [FirebaseAnalytics#logEvent](https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics#public-void-logevent-string-name,-bundle-params) (Android)
- [Analytics#logEvent](https://firebase.google.com/docs/reference/swift/firebaseanalytics/api/reference/Classes/Analytics#logevent_:parameters:) (iOS)

## [ユーザープロパティ](https://firebase.google.com/docs/analytics/user-properties)

イベントにはそのアプリのユーザー情報が紐付いて送信されています。
こちらも自動的に収集されるプロパティがあります。例えば年齢、性別、居住地域といったユーザーに関する情報や端末名、OSバージョンといった端末の情報があります。
cf. [事前定義されたユーザー ディメンション](https://support.google.com/firebase/answer/6317486)

### 独自のプロパティを設定する

プロパティもkey-value形式で設定できます。
ただこちらは予めConsoleでキーを設定しておく必要があります。

```kotlin:Kotlin
import com.google.firebase.analytics.FirebaseAnalytics

FirebaseAnalytics.getInstance(context).setUserProperty("email", "hoge@example.com")
```

cf. [ユーザープロパティの設定と登録](https://support.google.com/firebase/answer/6317519?hl=ja&ref_topic=6317489#create-property)

ユーザープロパティはイベントのフィルターとして利用できます。

cf. [レポート設定](https://support.google.com/firebase/answer/6317500?hl=ja)

# 実際の活用例

方針としてクライアント側でしか収集できないようなことをハンドリングした方がよいです。
サーバー側で解析できるようなAPIのリクエスト数やエラーを解析したい場合、Analyticsは向いていないかもしれません。

またアプリのクラッシュや例外を解析するには[Firebase Crashlytics](https://firebase.google.com/docs/crashlytics/get-started?hl=ja)というサービスがあるので、こちらも合わせて導入しておくと便利です。


## どちらの導線が多く利用されているか調べる

例えばユーザーをブロックする機能があり、その操作をするには2つの導線があるとします。
そのどちらが多く利用されているかを調べるにはこのように

```kotlin:Kotlin
// ユーザープロフィールから
firebaseAnalytics.logEvent("block_user") {
    param("from", "profile_view")
}

// ツイートから
firebaseAnalytics.logEvent("block_user") {
    param("from", "tweet")
}
```

別の画面で同じイベントを送信するようにし、カスタムパラメータでどちらの導線から実行されたかを与えておきます。

そしてこの`from`というパラメータをConsoleで分析できるようにするために、[カスタムディメンションを設定](https://support.google.com/firebase/answer/10075209)しておきます。
用途は異なりますがデモプロジェクトだと、[level_complete](https://console.firebase.google.com/u/0/project/fir-demo-project/analytics/app/android:com.labpixies.flood/events/~2Freport~2Flevel_complete%3Ft%3D1608031997523&fpn%3D300830567303&swu%3D1&sgu%3D1&sus%3Dupgraded&params%3D_u..pageSize%253D25%2526_r..eventId%253Dlevel_complete&cs%3Dapp.m.events.detail&r%3Ddefault&g%3D1?hl=ja)イベントの`level_name[post_score]`が似たような結果になると思います。

## 状態を持つ画面を区別する

例えば`TweetActivity`というActivityが2つの状態を持っているとします。
デフォルトではActivityの名前が画面の名前として収集されるので、状態を判別できません。
その場合、このように手動で画面の名前を設定することで区別することができます。

```kotlin:Kotlin
// ツイート投稿画面
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
    param(FirebaseAnalytics.Param.SCREEN_NAME, "PostTweetView")
    param(FirebaseAnalytics.Param.SCREEN_CLASS, "TweetActivity")
}

// ツイート編集画面
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
    param(FirebaseAnalytics.Param.SCREEN_NAME, "EditTweetView")
    param(FirebaseAnalytics.Param.SCREEN_CLASS, "TweetActivity")
}
```

cf. [画面表示の追跡](https://firebase.google.com/docs/analytics/screenviews)

Consoleだと[screen_view](https://console.firebase.google.com/u/0/project/fir-demo-project/analytics/app/android:com.labpixies.flood/events/~2Freport~2Fscreen_view%3Ft%3D1608031997523&fpn%3D300830567303&swu%3D1&sgu%3D1&sus%3Dupgraded&params%3D_u..pageSize%253D25%2526_r..eventId%253Dscreen_view&cs%3Dapp.m.events.detail&r%3Dscreen_view&g%3D1?hl=ja)イベントの`ユーザーエンゲージメント` → `スクリーン名`から確認できます。

## 利用時間を集計する

例えば通話時間を集計したい場合、通話を始めてから切るまでの時間をタイマーかなにかで測定しておいて、それをイベントのカスタムパラメータに設定しておけば集計することができます。

デモプロジェクトだと[post_score](https://console.firebase.google.com/u/0/project/fir-demo-project/analytics/app/android:com.labpixies.flood/events/~2Freport~2Fpost_score%3Ft%3D1608034420455&fpn%3D300830567303&swu%3D1&sgu%3D1&sus%3Dupgraded&params%3D_u..pageSize%253D25%2526_r..eventId%253Dpost_score&cs%3Dapp.m.events.detail&r%3Ddefault&g%3D1?hl=ja)イベントの`score`パラメータが該当します。
数値の単位はConsole側の[カスタム指標設定](https://support.google.com/firebase/answer/10075209?hl=ja)で設定できます。

# おわりに

Firebase向けGoogle Analyticsを導入すると、機能の追加や変更をするにあたって正確なデータを元に検討することができます。
途中でイベントやユーザープロパティを実装してもそれ以前のデータは収集できないので、初期段階で実装しておくことをおすすめします。
ライブラリを入れるだけでも価値があるので、是非使ってみてください。