※本記事は、ある程度、Firebase AB Testingを使い込んでいる人を対象としています。予めご承知おきくださいませ。
Firebase AB Testing、とても便利ですよね。
ユーザー調査において、定性調査(ユーザーテスト、インタビュー)をするのは、エンジニアとしては荷が重いですね。
AB Testingによる定量調査(イベント数から優位性判断)ならば、手が届きそうな感じがしませんか?
※突き詰めたら、これはこれで専門知識が必要なんですけどね。。
筆者も、日々、プログラミングとAB Testingの結果を眺めながら生活をしていますが、ある日のスプリントレビューで衝撃の展開が発生しました。
AB Testingにアサインされたユーザのバリアントが切り替わっている
先週まで圧倒的に優位だったバリアントが、次の週で突然、優位性が逆転しているという現象が発生しました。
弊社サーバログも合わせて解析したところ、どうやら所属バリアントが切り替わっているユーザーが存在していると推測されました。
テスト期間中に所属バリアントが切り替わってしまったら致命的ですね。テストの意味が無くなってしまいます。
ここから我々の長きにわたる(?)解析、実験のサイクルが始まりました。
色々と大変だったので詳細をモリモリ書きたい所ですが、結果だけ記載しますね。
少しでも同じ轍を踏む人が減ることを願っています。
環境
implementation "com.google.firebase:firebase-config:18.0.0"
原因:FirebaseRemoteConfigへのfetch方法に問題があった
問題が発生していたコードは、FirebaseRemoteConfig#fetch メソッドでRemoteConfigを取得後、 FirebaseRemoteConfig#activate をコールしていました。
すると、activateを呼んだ直後はAB Testingで指定した値は取得できず、もう一度fetch→activateをしないといけない事が分かりました。
試行錯誤の結果、FirebaseRemoteConfig#fetchAndActivateを利用すると、初回からAB Testingのバリアントで指定した値が取得出来ました。
まとめると、以下です。
Firebase側の設定
RemoteConfig = key : "testKey", value = "UnassignedValue"
AB Testing
Variant1 = key : "testKey", value = "AssignedXXXValue"
Variant2 = key : "testKey", value = "AssignedYYYValue"
FirebaseRemoteConfig#fetch, FirebaseRemoteConfig#activate を使った場合
初回のfetch結果では"testKey", value = "UnassignedValue"が取得される。
activate後に再度、fetchを実行すると、Variant1 or Variant2の値が返却される。
FirebaseRemoteConfig#fetchAndActivate を使った場合
初回のfetch結果で Variant1 or Variant2の値が返却される。
上記の振る舞いにより、利用初日はバリアント1に所属していたユーザーが、アプリを終了後、次の日起動したらバリアント2に切り替わってしまうという事態を引き起こしていたのです。
余談:FirebaseInstance Id が変わらない限り、所属バリアントが変わることは無い
Firebaseサポート様からご教示頂いた内容です。
この観点で再調査してみたところ、我々のアプリの初期化シーケンスで FirebaseInstance Id の削除が呼ばれるパターンが存在していました。
つまり、AB Testingにアサイン後に、InstnceIdを削除してしまった為、次回アプリ起動時に再アサインされ、バリアントが切り替わっていた可能性がありました。
おわりに
本件はFirebaseサポート様とも共有していまして、もし、記事の内容に誤り等がありましたら、速やかに修正しますね。
皆様の楽しいAB Testingライフに貢献できれば幸いです。