FirestoreとRealtime Databaseとわたし(たち)

この記事は Goodpatch Advent Calendar 2020 7日目の記事です!

はじめに

Googleが提供するFirebaseには、FirestoreとRealtime Databaseの2つのデータベースが存在します。私が所属するStrapチームでは、これらのデータベースを活用してサービス開発を行っています。
今回は、この2つのデータベースの違いと、その特徴から弊チームで考えた使い分けについてご紹介します。

FirestoreとRealtime Database

Wikipediaによると、Firebaseはもともと2011年に設立され、前身の企業で利用していたチャットシステムに利用されていたリアルタイムアーキテクチャを元に開発された、Realtime Databaseを提供する企業でした。
その後、HostingやAuthenticationなどの機能の追加を経てmBaaSとなり、2014年にGoogleに買収されました。
そしてGoogleの買収後の2017年に登場した、新たな後継データベースがFirestoreです。

データベースの特徴と比較

Realtime DatabaseとFirestoreの特徴を公式サイトを元に確認してみましょう。

Realtime DatabaseとFirestore

両者には様々な違いがありますが、アプリケーションを構築する上での大きな違いとしては、データモデルや、クエリの柔軟性 が挙げられます。

また、課金体系にも違いがあり、Realtime Databaseは下りのデータ量と保存量に対して課金されるのに対して、Firestoreはそれらに加えてデータベースオペレーションに対しても課金されます。
一見Firestoreのほうが高コストのように見えますが、課金レートはRealtime Databaseに比べて低く設定されているようです。

- Understand Realtime Database Billing | Firebase Realtime Database
- Understand Cloud Firestore billing | Firebase

結論: まずはFirestoreで検討する

さっそくの結論ですが、2020年現在、公式ドキュメントにも記載があるとおり、基本的にはFirestoreを利用することがおすすめされます。

先の比較の通り、Firestoreではデータ構造の作りやすさや柔軟なクエリのサポートなど、Realtime Databaseと比較して有利な点が数多くあります。

ある程度の規模で提供するアプリケーションであれば、Security Ruleで提供される機能の多さからも、Firestoreのほうが、より複雑な要件にも対応しやすいはずです。

Realtime Databaseの使い所

では、どんなときにRealtime Databaseを利用する場面があるでしょうか。

Realtime DatabaseはFirestoreに比べてレイテンシが優れていて、Firestoreとは課金体型が異なり、Realtime Databaseでは下りの帯域と保存容量に対して課金されます。

このようなことから、よりリアルタイム性が求められる要件や、読み取りに対して書き込みの頻度が多い場面では、Realtime Databaseが選択肢として挙がりそうです。

公式ドキュメントでは、ユーザーのオンライン状態を表示するようなプレゼンスの機能を例にとって、Realtime DatabaseとFirestoreの併用を提案しています。

Realtime Databaseにはユーザーのオンライン状態を自動的に書き込む独自のパスが存在し、これを利用したソリューションです。

ロールベースアクセス制御する場合は注意

Realtime DatabaseをFirestoreと併用する上では注意点もあります。
アプリケーションで、ある程度複雑なロールベースのアクセス制御を行っている場合には、特に注意が必要です。

具体的な事例を挙げてみます。

Firestore上でロールベースのアクセス制御を行い、かつFirestoreにロール情報を保存し、FirestoreのSecurity Ruleで参照し制御しているような場合には、そのFirestoreのロール情報をRealtime Databaseは参照することができません。

例えば、ロールや所属するグループによって公開する情報を厳格に制御したい場合には、Realtime Databaseに保存する情報はIDなどの最低限の情報にするなどの対策が必要になるでしょう。

Realtime Database - Firestoreの併用

先のプレゼンスを例に取ると、特定のロールやグループにだけプレゼンスを提供するには、Firebase Authenticationの提供するCustom Claimsとの連携が必要になります。

しかし、Custom Claimsには1ユーザーあたり1KBのサイズ制限が存在するため、構築しようとするアプリケーションによっては、その設計と運用を慎重に検討する必要があるでしょう。

Custom Claimsを利用した認可情報の共有

こちらの制限は、Cloud Storageと連携する場合にも当てはまります。

チーム内での運用

私が所属するStrapチームでは、FirebaseやGCPを利用したサービスを開発しています。

サービス内でFirestoreとRealtime Databaseを適材適所で活用できるように、弊チームでは、これまで紹介したような特徴や課題を踏まえて、次のようなルールを設定しています。

1. 永続化、厳格なアクセス制御が必要なデータを含め基本的にはFirestoreを利用 2. 揮発データ、リアルタイム性が求められる機能、書き込み頻度が高い機能の場合はRealtime Databaseを検討 3. チームメンバー間での共有が不要なデータ、揮発データ、秘匿性の低いデータについてはlocal storageを検討する

具体的には、ユーザーのプレゼンス表示やカーソル表示にはRealtime Databaseを活用しています。

実装例: カーソル

Strapで提供するチームメンバーのカーソル表示は、これらのルールに沿ってFirestoreとRealtime Databaseを併用して実現しています。

【開発NEWS🏗️】誰が・どこで・どんな操作をしているかがわかる、カーソル機能がリリースされました!共同編集が一層楽しくなり、Gp社内も沸いてます…😊
Strapは、コラボレーションの可能性を広げるクラウドワークスペースとして着々と開発をすすめています
夏の正式版リリースまでどうぞお楽しみに! pic.twitter.com/rjjvjQjkOB

— Strap (@strap_app) June 4, 2020

カーソルの位置情報は、他ユーザーにリアルタイムに反映するため頻度高く書き込む必要がありますが、データの保存は利用中のみに限られるため、先のルールに照らし合わせてRealtime Databaseでの実現が妥当だと判断しています。

実際には、同時利用中のユーザー数による書き込みの制限や、無操作時のプレゼンスとの連動など細かな制御も行っていますが、比較的低コストでの運用が実現できています。

まとめ

StrapチームにおけるFirestoreとRealtime Databaseの活用についてご紹介しました。

現代においては、Firebaseでデータベースを利用する場合、Firestoreが第一の選択肢となることは間違いありませんが、Realtime Databaseの特徴についても知っておくことで、低コストで最適な体験が実現できることもあります。

Strapにおける技術選定や技術スタックについては、こちらの記事が参考になるかもしれません。

最後に完全なるプロモーションですが、今回紹介したStrapについてはこちらのサービスページから詳細をご確認くださいませ!