kotlinでGoogleAnalyticsとFirebaseAnalyticsにイベント両送信

この記事は [Wanoグループ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/wano-group)の11日目の記事になります。
社内共有ツールの方で随時書いてたら肝心のこっちに書くネタがない...

## GoogleAnalytics と FirebaseAnalytics両方に送りたい

ネイティブアプリのログはFirebaseの方にどんどん寄せていこう、というGoogle先生の強い意思を感じる今日この頃です。
しかしいかんせんGUIがわかりづらい。
特に画面間のユーザー移動を出そうとしただけでも、Firebaseの裏側で蓄積されているBigQueryのデータを直接いじらなければならなくなったりします。
一方、GoogleAnalyticsは歴史の蓄積があり、エンジニア以外の人員もある程度見方がわかっていることも多いかと思います。
今回はFireBaseだけでなく、GoogleAnalyticsの画面でも実験的に画面遷移イベントやアクションイベントを送ってみます。
なお、FirebaseからGoogleAnalyticsへの同期機能もあるのですが、こいつもまた取り回しが悪いです。
ここでは自分たちでハンドリングしたいため、手動で両送信します。

```kotlin
object Logger {

    fun sendScreenName(activity : Activity,  screenName : String){

        val app = MainApplication.getApplication()
        val tracker = app.defaultTracker

        try {

            //Google Analytics
            tracker.setScreenName(screenName)
            tracker.send(HitBuilders.ScreenViewBuilder().build())

            //Firebase Analytics
            var mHandler = Handler(Looper.getMainLooper())

            mHandler.post(Runnable {
                var fAnalytics = app.firebaseAnalytics;
                fAnalytics.setCurrentScreen(activity , screenName , null)
                // ここに処理
            })

        } catch (error : Exception) {
            Log.e(TAG , error.toString())
        }
    }

    fun sendEvent(category : String , action : String , labelKey : String , labelValue :String , numValue : Long){
        val app = MainApplication.getApplication()
        val firebaseAnalytics = app.firebaseAnalytics
        val tracker = app.defaultTracker

        try {
            // GA
            tracker.send(HitBuilders.EventBuilder()
                    .setCategory(category)
                    .setAction(action)
                    .setLabel(labelKey + ":" + labelValue)
                    .setValue(numValue)
                    .build()
            )
            // FA
            val bundle = Bundle()
            bundle.putString(labelKey , labelValue)
            bundle.putLong("value" , numValue)
            firebaseAnalytics.logEvent(category + "_" + action , bundle)

        } catch (error : Exception) {
            Log.e("¥TAG , error.toString())
        }
    }
}

```

## マッピング
例えば、GoogleAnalyticsの方には生えているCategoryという概念はFirebaseの方にはなく、BundleをKVS的に扱って自在に値を格納できるだけです。
なので一旦独自のマッピングルールを設けて送信することにしています。

Firebaseの方の

```
firebaseAnalytics.logEvent(category + "_" + action , bundle)
```
という部分ですね。
また、Google Analyticsの方には連続した数値を専門に扱う ``` .setValue(数値) ```　が生えているのですが、これもFirebase上はbundleの前に等価なため、苦肉の策でvalueというkeyを追加しています。valueとはって話ですね。

## その他

また、これを搭載したアプリでは、実際のイベント送信のトリガーはReactNativeから送っているので一応ついでに載せておきます。
受信側

```kotlin
    @ReactMethod
    fun setScreenName(screenName : String){
        var activity = getCurrentActivity();
        if (activity != null){
            Logger.sendScreenName(activity , screenName)
        }
    }

    @ReactMethod
    fun sendEvent(category : String , action : String , labelKey : String , labelValue :String, numValue : Int){

      Logger.sendEvent(category , action , labelKey , labelValue , numValue.toLong())
    }

    @ReactMethod
    fun setUserID(userID :String){
        MainApplication.getApplication().setUserID(userID)
    }

```

送信側

```typescript

import { NativeModules } from 'react-native';
const bridgeModuleNative : any = NativeModules["BridgeModule"];



export default class BridgeModule {

....
    public static setScreenName(name : string){
        bridgeModuleNative.setScreenName(name);
    }

    public static sendEvent(category : string , action : string , labelKey : string , labelValue :string , numValue : number = 1){
        const sendNum = numValue ? numValue : 1;
        bridgeModuleNative.sendEvent(category , action , labelKey , labelValue , sendNum);
    }

    public static setUserID(userID :string){
        bridgeModuleNative.setUserID(userID);
    }
}

```