Firebase Remote Configの運用で知ったこと・知っておくと良いこと / Things I Learned from Operation of Firebase Remote Config

Firebase Remote Configの運用で知ったこと・知っておくと良いこと / Things I Learned from Operation of Firebase Remote Config

2019年6月18日に合同会社DMMで行われたpotatotips #62で発表した資料です。
Firebase Remote Configを実装・運用した時に気づいたTIPSについて解説しました。

Poiboy(ポイボーイ) 出会い探しマッチングアプリ
https://poiboy.jp/

Firebase Remote Config (公式)
https://firebase.google.com/docs/remote-config?hl=ja

Firebase Remote Config を使ってA/Bテストをやってみよう - PSYENCE:MEDIA
https://tech.recruit-mp.co.jp/mobile/post-14940/

sgr-ksmt/Lobster - 🦐 Type-safe Firebase-RemoteConfig helper library 🦐
https://github.com/sgr-ksmt/Lobster

jmatsu/remocon - a CLI for managing Firebase Remote Config based on YAML files.
https://github.com/jmatsu/remocon

iOSアプリのテストを書きたいのに書けないあなたへ
https://speakerdeck.com/imaizume/how-you-should-start-to-write-your-first-unit-test-for-ios

環境ごとにFirebaseプロジェクトを使い分ける方法 (@giiiita)
https://qiita.com/giiiita/items/be71c14a59f596bc4001

1a74617b91d2757b839b9cf3614648ce?s=128

Tomohiro Imaizumi

June 18, 2019
Tweet

Transcript

  1. 4.

    参考: Remote Configの導⼊⽅法 (Swift 4) * application(didFinishLaunchingWithOptions)内に以下を追加 pod 'Firebase/Analytics' pod

    'Firebase/RemoteConfig' Podfile FirebaseApp.configure() AppDelegate内 * Podfileに追加 * 取得したいフラグにデフォルト値を設定してから値を取得 let remoteConfig = RemoteConfig.remoteConfig() let parameter = “sample_beta_feature" /// デフォルト値は取得不能時等に使われる remoteConfig.setDefaults([parameter: false as NSObject]) /// 必要な型にキャストする let isBeta = remoteConfig[parameter].boolValue if isBeta { /* betaユーザーに対する処理 */ } 使いたい場所
  2. 8.

    パラメータを表すenumを定義 enum BoolParameter { case beta_feature_A case beta_feature_B … var

    defaultValue: Bool { switch self { case .beta_feature_A: return false … } } } enum StringParameter { … } enum NumberParameter { … } パラメータ型ごとのenum 型の種類に応じて 定義が必要 パラメータ名とデフォルト値を定義
  3. 9.

    パラメータ値の取得処理 FirebaseStore { func boolValue(for key: BoolParameter) -> Bool {

    let remoteConfig = RemoteConfig.remoteConfig() remoteConfig.setDefaults(key.defaultValue) return remoteConfig[key.rawValue].boolValue } func stringValue(for key: StringParameter) -> String? { let remoteConfig = RemoteConfig.remoteConfig() remoteConfig.setDefaults(key.defaultValue) return remoteConfig[key.rawValue].stringValue } } let store = FirebaseStore() let boolValue: Bool = store.boolValue(for: .beta_test_A) let stringValue: String? = store.stringValue(for: .beta_test_B) パラメータ値の取得処理 補完やfind usageの機能も利⽤可能に 取得⽤メソッドも 型ごとに⽤意
  4. 10.

    (アプリ側)パラメータ管理⽤OSS: Lobster • 管理周りの⾃前実装が不要に • 扱えるデータ型が拡張される (CollectionなどもOK!) https://github.com/sgr-ksmt/Lobster extension ConfigKeys

    { static let text = ConfigKey<String>("text") } let text: String = Lobster.shared[.text] Lobsterでの実装 使った⼈いたらぜひ話を聞きたいです❗
  5. 11.

    (コンソール)パラメータ管理⽤OSS: remocon • YAMLにパラメータを定義 • コマンドで更新 • コンソールを触らないので 安全に管理できそう •

    エンジニアだけが触る前提 じゃないと難しい? https://github.com/jmatsu/remocon こちらも使った⼈いたら話を聞きたいです❗
  6. 14.

    補⾜: 環境ごとに設定を分ける⽅法 let options = FirebaseOptions( contentsOfFile: FirebaseConfig.resourceFilePath())! FirebaseApp.configure(options: options)

    AppDelegate内 struct FirebaseConfig { static func resourceFilePath() -> String { #if DEBUG return Bundle.main.path(forResource: "GoogleService-development-Info", ofType: ".plist")! #else return Bundle.main.path(forResource: "GoogleService-Info", ofType: ".plist")! #endif } } Config 参考: https://qiita.com/giiiita/items/be71c14a59f596bc4001 QAやデバッグ⽤のパラメータを設定可能なので便利
  7. 15.

    抽象への依存を可能にするprotocolを定義 /// Bool型のパラメータを返すStoreに要求されるインターフェイス protocol BoolStoreProtocol { func boolValue(for key: BoolParameter)

    -> Bool } /// String?型のパラメータを返すStoreに要求されるインターフェイス protocol StringStoreProtocol { func stringValue(for key: StringParameter) -> String? } StoreProtocol.swift Presenter StoreProtocol Store Stub Firebaseから 取得した値 任意の指定値 true protocolで抽象化
  8. 16.

    Remote Configの値を返すStore class FirebaseStore {} extension FirebaseStore: BoolStoreProtocol { func

    value(for key: BoolParameter) -> Bool { let remoteConfig = RemoteConfig.remoteConfig() remoteConfig.setDefaults(key.defaultValue) return remoteConfig[key.name].boolValue } } extension FirebaseStore: StringStoreProtocol { func value(for key: StringParameter) -> String? { let remoteConfig = RemoteConfig.remoteConfig() remoteConfig.setDefaults(key.defaultValue) return remoteConfig[key.name].stringValue } } FirebaseStore.swift Storeは型:class = n:1で定義
  9. 17.

    任意の値を返すStub // 任意のパラメータで任意の値を返すことも可能 /// 常にfalseを返すスタブ class BoolStoreStub: BoolStoreProtocol { func

    boolValue(for key: BoolParameter) -> Bool { return false } } /// 常に"You are a beta user!"を返すスタブ class StringStoreStub: StringStoreProtocol { func stringValue(for key: StringParameter) -> String { return "You are a beta user!" } } StoreStub.swift Stubは型:class = 1:1で定義
  10. 18.

    呼び出し側 let boolStore: BoolStoreProtocol = FirebaseStore() let realBoolValue = boolStore.value(for:

    .beta_test_A) // true or false let boolStub: BoolStoreProtocol = BoolStoreStub() let stubBoolValue = boolStub.value(for: .beta_test_A) // always true class SomePresenter { private let firebase: BoolStoreProtocol init(_ firebase: BoolStoreProtocol = FirebaseStore()) { self.firebase = firebase } … } let realPresenter: SomePresenter = .init() let stubPresenter: SomePresenter = .init(boolStub) FirebaseRemoteConfigParameter.swift 抽象への依存でStubとStoreを区別なく使⽤可能に
  11. 21.

    A/Bテストのやり⽅ • Poiboyでは… • ロジック切り替え: Firebase Remote Config • ログ送信:

    Treasure Data / Repro 等 • Firebase A/B Testing • 2019年6⽉現在beta版 • ⚠予めユーザープロパティを送る必要あり TreasureData.sendEvent( eventType: .someEvent, … isBetaUser: firebase.value(forKey: .beta_user_A) ) TreasureDataへのイベント送信 ロジック切り替えとイベント収集は別ツールでもOK✂
  12. 22.

    運⽤ルールの明⽂化 / ワークフローへの組み込み ルール・ワークフローの例 • パラメータ作成時 • 対応が分かるようフラグ名と条件名は同じに • 説明欄に意図や施策を⼈間の⾔葉で書く

    • A/Bテスト終わってもパラメータが放置される問題 • 毎スプリントで不要パラメータ消去タスクを積む • 事故防⽌のためQA項⽬に追加 • AndroidとiOSでパラメータ分ける時 • Androidは”a_”プレフィックスをつける 他社さんの運⽤周りのノウハウもぜひ知りたいです
  13. 23.

    まとめ ✓ パラメータはenumで管理 ✓ 複雑な管理はライブラリを使おう ✓ 開発⽤と本番⽤でプロジェクトを分けよう ✓ スタブ化するとテスト時に便利 ✓

    現在のパラメータをどこかに表⽰しよう ✓ フラグ管理とログ集計のツールは別でもOK ✓ 運⽤フローは早めに明⽂化 懇親会でもぜひ話しましょう
  14. 24.

    参考リンク • Poiboy(ポイボーイ) 出会い探しマッチングアプリ https://poiboy.jp/ • Firebase Remote Config (公式)

    https://firebase.google.com/docs/remote-config?hl=ja • Firebase Remote Config を使ってA/Bテストをやってみよう - PSYENCE:MEDIA https://tech.recruit-mp.co.jp/mobile/post-14940/ • sgr-ksmt/Lobster - Type-safe Firebase-RemoteConfig helper library https://github.com/sgr-ksmt/Lobster • jmatsu/remocon - a CLI for managing Firebase Remote Config based on YAML files. https://github.com/jmatsu/remocon • iOSアプリのテストを書きたいのに書けないあなたへ https://speakerdeck.com/imaizume/how-you-should-start-to-write-your-first-unit- test-for-ios • 環境ごとにFirebaseプロジェクトを使い分ける⽅法 (@giiiita) https://qiita.com/giiiita/items/be71c14a59f596bc4001