PhpStormと僕

日々周りを巻き込むことをモットーに。気まぐれでJetBrains製のIDEネタとか書いてます。

Firebaseに関するディスカッション形式のMeetup FireTips#1を開催しました

アルは全部Firebaseで開発しているんですが、Firebaseをチームで使っているとチュートリアルやプロダクトの0→10くらいのフェイズのノウハウは結構あるものの、それ以降のプロダクトやチームのスケール期におけるノウハウがあまりなくて、世のエンジニアはどう向き合っているのかな〜って悩むことが多々ありました。そんな折にズボラ旅を作っているHotSpringの ぽちさんからお声がけがあってFirebase関連のTips持ち寄りの勉強会をやってみようという運びになりまして。

そんなわけで、企画から少し間は開いてしまったものの、めでたくFireTipsという題名で第一回が開催されたので内容共有のエントリです。

場所

アル社オフィス ラウンジスペース(渋谷)

形式

飲み物、食べ物は各自持ち寄り

今回話したこと

Firebase Projectsでdev, test, staging, productionなどの複数環境をどうしている?どう作る、どうデータを同期反映しているか

  • 一旦dev, staging, productionを手作業で環境構築した上で使っている。
  • アル社の場合はCircleCI上で週次でproduction => devへのマスタデータの更新をやっている。
  • dev環境が複数人が占有しづらい(ブランチとかで)ので、声かけ運用でdev環境の明け渡しとかをしている。ここが開発のボトルネックになりがち。
  • Firestore Emulatorは、できることがローカルテストのモック程度なので開発用(dev)の置き換えには現時点ではならない。

Firestoreにスキーマ定義がなくてつらい問題とどう向き合うか?

  • 事象としては例えば画像アップロード系の機能を実装するときに、Android/iOSがそれぞれクライアントで実装すると、カラムがnullableなのかカラムなしなのか空文字入れるのかとか、トランザクションでの処理が各クライアントの実装に依存する、というつらみ
    • Write処理をすべてCloud Functionsに寄せればとりあえずは問題の事象は少しは減る(Cloud Functionsのコードを読めばわかる)が、結局処理がBackendに寄ってしまうので著しくスピードが落ちる/Firestore Wayからは外れるしイケてない。
  • Firestore上のデータを参照したときにカラムやSub Collectionが存在しなかったときに、「そのカラム/Sub Collectionは常に存在しない」「特定の条件化では存在するが、そうでないときもある(その条件もデータからは読み取れない)」というつらみ
  • 現状ベターな解決策なし。求ム情報。

どういう処理をAPI処理(例えばCloud Functions)に寄せて、どういうものはフロントで処理するか

  • 無駄にCloud Functionsの処理を追加したくないし、追加したらさらにお金も掛かるので、極力直にフロントから処理したいというのもある。
  • トランザクション処理やフロントからは参照されたくないセキュアな処理、複数Collectionに跨がる処理などはCloud Functions側でやりたいが、それ以外は極力フロントでやりたい。
    • ただし前述のスキーマ定義がないが故のつらみで、AndroidiOSで処理が(同じロジックで実装したつもりだが)異なってしまうパターンも多々ある。

Sub Collectionで持つか、Root Collectionで持つか?

  • データ構造的にはSub Collectionの方がベターな感があるが、現状は「親Documentを特定していない状態ではSub Collectionに対してQuery(whereなど)が使えない」というとても大きな制約がある
  • HotSpring社ではどこになにがあるのかが分からなくなるのを避けるために、今はRoot Collectionに寄せている
  • アル社は「(firestore.ruleを踏まえ)横断的に検索する可能性がアル場合はRoot Collectionに、そうでなくデータが階層(ドキュメント)構造になる場合にはSub Collection」にデータを持つようにしている

Firestore Rule の本番反映へのフロー

  • 手作業でdevを更新したらstaging, productionに反映する
    • 「メンテナが一人だから成り立っているという側面もあるかも」
  • firestore.ruleで管理して、本番デプロイのタイミングでデプロイ
    • 必要な箇所(iOSやWeb)とデプロイのタイミング(Cloud Functions)が違うのでフローが煩雑でつらい

複数プロジェクトの認証を共有プロジェクトによるFirebase Authentication実現するのはどうか?

  • 良さそう!
  • 共有プロジェクト側のFirebase Authenticationでログインしている状態を、別のプロジェクトのFirestore側でcontext.authが引き継げるかどうか?がポイントになるが、検証してみないと分からない!

Cloud Functionsの自動デプロイ問題

  • 環境変数を .runtimeConfig で管理している場合、事前に環境変数を書き換えてProductionへデプロイ反映しておく必要がある(=人力作業が発生する)
    • .runtimeConfigをGitHubに乗っけてしまえばいける。
      • GHEという選択肢
  • 現状ベターな解決策案なし。

話せなかったこと(次回以降のネタになるかも)

  • Cloud Functionsのデプロイ時のDownTimeについて
  • AlgoliaのWeb Console上でフィルタをいい感じにデバッグする
  • Firebase Cloud Functions vs GCP Cloud Functions
  • Firestoreのnull型って使ってる?
  • FirestoreでcreatedAt, updatedAtみたいなTimestamp型について
  • 権限管理をFirebase Authenticationのcustom-claimでやったときにどう管理するか
  • Client Side Join vs 正規化 with Web Application
  • MySQL と Firestore の使い分け

第二回のお知らせ

こんなニッチだけど割と実践する上では悩むネタをゆるく話し合う場でした。 2回目は5/15あたりに開催します。 イベントページはまだ作らないつもりなんですが、もし参加興味ある方はTwitterとかでDMいただければと思います!