「Crieit Advent Calendar 2018」の記事です。2018年は、業務で「Firebase Realtime Database」を使った1年でした。
Realtime Databaseは、数ミリ秒で各クライアントへデータを同期します。はじめて使ったときは、とても感動しました。開発したシステムでは、リアルタイムのデータ表示が必要な、特定機能に限定してRealtime Databaseを投入しています。
色々と工夫した点がありますので、今回はその辺りの知見を共有します。
RDB(Relational Database)との併用
「Firebase Realtime Database」は、データベースとして単体で使うわけではなく、PostgreSQLと併用して運用しています。
それには、いくつかの理由があります。
- はじめて使うので、ミニマムにプロジェクトで採用し、様子を見ることにした
- データ容量や転送量に連動する従量課金のため、最低限のリアルタイム表示に必要なデータだけ置くことにした
- Realtime Databaseは、柔軟なクエリ発行が苦手です。管理画面をはじめとする、細かな検索条件が発生するシーンには不向きでした
棲み分けとしては、リアルタイム表示が必要なデータをRealtime Databaseに投入し、それ以外はRDB(PostgreSQL)に保存しています。
また、Firebase Console上の誤操作で、データを上書きしたり消失できてしまう可能性があります。そこで、復旧スクリプトも用意しました。
具体的には、PostgreSQLにあるマスターデータを元にして、API経由でデータを再セットするスクリプトです。ただ、一度も出番はなかったです。
セキュアなデータはRDB(PostgreSQL)に置く
また、PostgreSQLを併用しているもうひとつの理由に、セキュアなデータを置きたくなかった点があります。
後述するセキュリティルールを工夫すれば対策も可能ですが、保険をかけて、セキュアなデータはサーバーサイドのRDBに暗号化して保存してします。
セキュリティルールの調整で、書き込みを拒否する
セキュリティルールは、基本的に以下の設定で運用しています。私の場合、書き込みは許可せず運用することにしました。
また、リアルタイムのデータ表示に必要な特定のテーブルに絞って、読み込みを開放しています。
{ "rules": { ".read": false, ".write": false, "sampletable": { ".read": "auth != null", ".write": false } } }
書き込みを拒否した理由は、主に以下の3点です。
- PostgreSQLのマスターデータにも反映したかったので、書き込みはサーバーサイドで処理したかった
- フロントエンドJSから直接データを書き込ませないことで、安全性を高めたかった
- 認証は自前でやっており、Firebase Authenticationで認証していない。そのため、細かな書き込み権限の制御が難しかった
なお、書き込みを許可しなかったとしても、Admin用のライブラリを使えば書き込みは可能です。PHPには公式のAdmin SDKがなかったので、OSSを利用しました。
読み込み側の権限は「auth != null」にしています。念のため、Firebase Authenticationの匿名認証を挟んで運用している形です。
GCP(Google Cloud Platform)と連動している点に注意
Firebaseのプロジェクトを開設すると、GCP(Google Cloud Platform)のConsoleでもアクセスできるようになります。この点はかなり重要です。
私が技術書典4で頒布した「Realtime Database x React本」でも、注意事項を書いてます。抜粋して掲載します。
「APIとサービス」の認証情報を確認すると、Firebaseが自動で作成したキーがあることが分かります。そして、APIキーにおける警告マークは、APIキーが無制限であることを示しています。実運用で使用される場合は、設定は必須であると言えます。開発段階でも、可能な限り制限を設定することが望ましいでしょう。
WEBサービスであればリファラで、モバイルアプリであればバンドルIDなどでAPIキーを制限するのが基本形です。これを設定しておかないと、Firebase用のアクセスAPIキーが無制限状態で運用されてしまいます。
少し内容が古くなってしまいましたが、技術書典4で頒布した本にもFirebaseの概要を書いてます。無料でダウンロードできます。
Realtime Databaseの実装は、メルカリを参考にするのがオススメ!
私がプロジェクトで採用した構成は、「PHPカンファレンス2017のメルカリチャンネル」をベースにしています。
会場でメルカリの@sota1235さんに質問して、「半年ほど運用しているが、一度もダウンしたことはない」という返答をもらったのが、採用の決め手になりました。
メルカリチャンネルにおけるRealtime Databaseの知見は、他の記事でも共有されています。ぜひ参考にしましょう!
Cloud Firestoreとの関係性
Realtime Databaseの対抗馬として、Cloud Firestoreがあります。
個人的には、以下のような印象を持っています。
- Cloud Firestoreは、まだベータ版である
- クエリの柔軟性は、Cloud Firestoreのほうが高い
Cloud Firestoreの特徴である「クエリ処理の機能性、効率性、柔軟性」は、とても魅力的です。
さいごに
リアルタイムのデータ表示が必要な、特定機能に限定してRealtime Databaseを投入しました。感触はとても良いです。
また、オフライン対応があるのも魅力的です。もしデータ同期に失敗しても、クライアントがオンラインになったら、自動的に同期を再開します。これを自前のWebSocketで実装するとしたら、相応の苦労が必要なことは間違いありません。
巨人の肩の上にのることのメリットを、改めて実感した1年でした。