見出し画像

Firebaseを使ってサービスを立ち上げた時につまずいたポイント

この記事は「Firebase Advent Calendar 2020」の15日目です。

以前会社の中で、とあるtoB向けSaaSの立ち上げプロジェクトに参画していたのですが、開発にあたりFirebaseを採用して進めておりました。Firebaseを本格的に案件で使用するのは初めてだったので、手探り調査しながら開発していたのですが、その過程で予定通り行かなかった箇所、ハマってしまったポイントがあったので、備忘録的に書いて行きたいと思います。

本当にちょっとした部分なので、そんなの知ってるよ!みたいな内容でしたらご容赦ください・・・

そもそもなんでFirebaseを選択したか

・リリースまでのスピード感を最優先したかった
・ランニングコストを最小限に抑えたかった

上記2つが大きな理由です。
サービスの立ち上げ時には、アイデアが固まった後、スモールスタートでいいから早くプロダクトを世に出すことが求められます。プロダクトを改善していくための一番の情報源は「ユーザーの声」なので、不完全なものでも積極的にアウトプットし、自分たちが作っているものがちゃんと市場に求められているものかどうか判断しながら開発します。
リーンスタートアップって本に書いてありました

Firebaseならば認証やデータI/Oのバックエンドと、サーバ(ホスティング環境)を一括で用意&マネージドされるので、関わる人数の少ないサービス立ち上げ初期には重宝します。(=インフラ・バックエンド担当を最小限リソースにできる)
加えて、従量課金でもあるので、仮にサービスが全然使われずアクセスが来なかった場合でも、その分だけかかった金額のみ支払えば良いため、コスト的な意味でのリスクヘッジにもなります。

サービス立ち上げにあたり、上記のような理由でFirebaseを技術選択したわけですが、手探りで開発していくと下記のようなハマったポイントが出てきました。

メンテナンスページを表示するためのリダイレクト設定におけるパフォーマンスの問題

サービス運用中、予期せぬ不具合が生じた場合は、とにかくメンテナンスページにリダイレクトさせたいです。
メンテナンス用の設定として、どのページを表示してもメンテナンスページにリダイレクトさせ、開発している社内IPからのアクセスのみ通す、というサーバ設定を組もうと思ったのですが、これが難しかったです。

Firebase Hosting単体ではBasic認証やIP制限などのサーバ設定をかけることはできず、Firebase Functionsを併用することで実現することはできます。
※やり方としてはこちらの記事のような形

このやり方を応用して、function/index.jsにNode.jsでサーバ設定ロジックを書くことができるので、IP制限やメンテナンスページ用のリダイレクト挙動を記述していくことはできます。
このやり方の場合、Firebase Hostingのファイルの閲覧先がFirebase Functionsとなるので、例えばブラウザで何かHTMLを表示する場合は、ブラウザ→FirebaseHosting→FirebaseFunctions(ファイル読み込み)→FirebaseHosting→ブラウザといったデータ取得の流れになります。

この時作られるFirebase Functionsのリージョン、us-centralしか指定することができません。
よって、ネットワーク的にどうしても一度アメリカに飛んでしまうことで、ページの表示にかなりの時間がかかってしまいます・・・
こちらの記事に詳しく書いていただいております。
開発中にページ表示の遅さが問題に上がった際に、こちらの内容が大きなボトルネックになっていたことがわかりました。

解決手法としては、Firebase HostingからGoogle App Engineにホスティング環境を移管しました。
Firebaseの機能だけでは、メンテナンスのオペレーション構築とサイトパフォーマンスのバランスを取れないだろうと判断したためです。
メンテナンスのオペレーションは、IP制限&リダイレクトの設定の代わりに、GAEデプロイ時にはバージョンごとにURLが発行されるので、ユーザートラフィックの無いバージョンでテストできるようなオペレーションとしました。

Firebase Authenticationのメールアドレス認証でログインできなくなってしまう場合が発生する問題

サービス開発の際に、メールアドレス及びGoogleアカウントでのログイン機能を実装しました。リリースの際に、それぞれ動作確認を行っていたのですが、メールアドレスで新規登録をしたはずなのにログインができなくなる事象が起きているとの報告が上がりました。

調査の結果わかったのが、複数認証プロバイダ紐付けの問題だったということです。複数認証プロバイダ紐付けとは、例えば今回でいうと、メールアドレス(gmail)とGoogleアカウント両方でログインできるようになることです。Firebaseでは同一のメールアドレス(gmail)でGoogle認証・メアド認証をそれぞれ行った場合、自動でそれぞれでログインできるように、認証アカウントを紐づけてくれます。ただ、「正しい認証用アカウントである」ということが保証されたプロバイダでないと認証紐付けができないそうでして、Googleアカウントでの認証の場合は、Firebase側で「正しい認証アカウント」であると認識されますが、メールアドレスの場合は新規登録の後に「メールアドレス確認」のフローを経ないと正しい認証用アカウントであると認識されません。(メールで認証用リンクを送る or 認証用コードを送信する、などのやつですね)
仮にメールアドレスの確認フローを経ないで、同じメールアドレス(Gmail)でGoogleログインを行った場合、Googleログインは今後もできますが、メールアドレスでのログインはできなくなります。

今回の開発ではメールアドレス登録から確認のフローを経る前にGoogleログインを行ったことにより発生した事象だということがわかったので、FAQなどにそういった事象の注意を追記することでいったんの対応としました。
結構なレアケではあるなと思いつつ、発生してしまった場合メールアドレスでは二度とログインできなくなってしまうので、なかなか厄介です。(メールアドレス紐付けのための機能を別途開発できそうかどうかは未調査)
※この事象、Firebaseの公式ドキュメントで以前見た気がしたのですがソースを見つけられず・・・もし知っている方いればご教授いただけると嬉しいです。

まとめ:サービス開発におけるFirebaseの使い所

上記のようなハマりポイントはありつつも、サービス立ち上げの際のFirebaseの効果は絶大だったなという所感です。
開発リソースと金額コストを最小限に抑えつつ、スピード重視でリリースにまで漕ぎ着けるには、Firebaseはなくてはならないサービスだなと感じております。
一方で、Firestoreでのデータの持ち方・具体的には例えばリレーションが貼れないということだったり、流せるクエリにも柔軟性がそこまで無いことからデータメンテのやりづらさなども感じているため、サービスをグロースさせる段階になったときはRDB + バックエンドサーバを構える構成に変更していくことも求められるだろうなとも思いました。

Firebaseのようなありもののサービスを組み合わせることで開発スピードをあげることとシステムの柔軟性は、ある程度はトレードオフなので、ミニマムリリースの際はどのあたりまでの柔軟性を捨てても良いと判断するか、また開発中に使用しているサービスではどうにもならないことが起こった場合、他のサービスで代替できないかor別のやり方などないかなど、開発者の方で柔軟性を持って対応できるかどうか、というのが問われそうだなと感じました。

あくまで一個人の所感なのですが、誰かの何かの助けになれば幸いです!


この記事が気に入ったらサポートをしてみませんか?