Firebase Realtime Database で Cloud Firestore を使用する

Firebase Realtime Database と Cloud Firestore の両方をアプリで使用し、ニーズに合わせて各データベース ソリューションの利点を活用することができます。たとえば、Cloud Firestore でプレゼンスを構築するで説明するように、Realtime Database でのプレゼンスのサポートを活用することができます。

詳細については、データベースの違いをご覧ください。

Cloud Firestore へのデータの移動

Realtime Database から Cloud Firestore にデータの一部を移行することを決定した場合は、次のフローを検討してください。どのデータベースにも固有のニーズと構造上の考慮事項があるため、自動化された移行パスはありません。移行パスを使用する代わりに、次の一般的な手順に従うことができます。

  1. データ構造とセキュリティ ルールを Realtime Database から Cloud Firestore にマッピングします。Realtime Database と Cloud Firestore はどちらも Firebase Authentication に依存しているため、アプリのユーザー認証を変更する必要はありません。ただし、セキュリティ ルールとデータモデルは異なります。データを Cloud Firestore に移動する前に、これらの違いを慎重に考慮する必要があります。

  2. 履歴データを移動します。Cloud Firestore で新しいデータ構造を設定するときに、既存のデータを Realtime Database から新しい Cloud Firestore インスタンスにマッピングし、移動できます。ただし、アプリで両方のデータベースを使用している場合は、Realtime Database から履歴データを移動する必要はありません。

  3. 新しいデータをリアルタイムで Firestore にミラーリングします。Cloud Functions を使用して、新しいデータを新しい Cloud Firestore データベースに書き込み、Realtime Database に追加します。

  4. Cloud Firestore を、移行したデータのプライマリ データベースにします。一部のデータの移行が完了したら、Cloud Firestore をプライマリ データベースとして使用し、移行したデータに Realtime Database を使用する状況を減らします。そのデータに Realtime Database を使用しているアプリのバージョンと、これらのバージョンのサポート継続をどのように計画するかについて検討します。

Realtime DatabaseCloud Firestore の両方の料金を確認してください。

データをマッピングする

Realtime Database のデータは単一ツリーとして構成されますが、Cloud Firestore はドキュメント、コレクション、およびサブコレクションを通じてより明示的なデータ階層をサポートします。Realtime Database から Cloud Firestore に一部のデータを移動する際には、データ アーキテクチャの変更も視野に入れて検討することをおすすめします。

考慮すべき主な違い

既存の Realtime Database ツリーから Cloud Firestore のドキュメントおよびコレクションにデータを移動する場合、次のようなデータベース間の主な違いにより、Cloud Firestore でのデータの構造に影響が及ぶ可能性があります。

  • 層が少ないクエリにより、階層的なデータ構造での柔軟性が増します。
  • 複雑なクエリにより、粒度が増し、重複データの必要性を減らします。
  • クエリカーソルにより、ページ設定がより堅牢になります。
  • トランザクションではすべてのデータに対する共通のルートが不要になり、効率性が向上します。
  • Realtime Database と Cloud Firestore の料金は異なります。多くの場合、Cloud Firestore は Realtime Database よりも費用がかかります。多数の小規模オペレーションを使用している場合は、その違いが特に顕著に表れます。データベースのオペレーション数を減らし、不要な書き込みを避けることを検討してください。Realtime Database と Cloud Firestore の料金の違いの詳細をご覧ください。

実施時におすすめの方法

次の例では、データベース間でデータを移動する際の考慮事項を取り上げます。Realtime Database と比べると、Cloud Firestore では低深度読み取りが利用でき、クエリの性能も向上しているので自然なデータ構造が可能です。

たとえば、ユーザーが世界中の都市の名所を見つけるのに役立つ、都市ガイドアプリを作っているとします。Realtime Database では低深度読み取りを行わないため、次のように 2 つの最上位ノードにデータを構造化する必要があります。

// /cities/$CITY_KEY
{
  name: "New York",
  population: 8000000,
  capital: False
}

// /city-landmark/$CITY_KEY/$LANDMARK_KEY
{
  name: "Empire State Building",
  category: "Architecture"
}

Cloud Firestore は低深度読み取りを行うので、コレクション内のドキュメントに対してクエリを実行してもサブコレクションのデータは取得されません。そのため、名所情報をサブコレクションに格納できます。

// /cities/$CITY_ID
{
  name: "New York",
  population: 8000000,
  capital: False,
  landmarks: [... subcollection ...]
}

ドキュメントのサイズの上限は 1 MB です。名所情報をサブコレクションとして格納すると、ネストされたリストで各都市のドキュメントを肥大化させずに小さく保つことができます。この点も、サブコレクションを使用する利点のひとつです。

Cloud Firestore には高度なクエリ機能が備わっているため、よくあるアクセス パターンに合わせてデータを複製する必要性が軽減されます。たとえば、都市ガイドアプリの画面で、世界各国の首都を人口順ですべて表示するとします。Realtime Database の場合、このリストを最も効率的に表示するには、次のように cities リストからデータを複製して首都のリストを別に保持する必要があります。

{
   cities: {
    // ...
   },

   capital-cities: {
     // ...
   }
}

Cloud Firestore では、クエリを 1 件実行するだけで人口順に並べた首都のリストを作成できます。

db.collection('cities')
    .where('capital', '==', true)
    .orderBy('population')

詳しくは Cloud Firestore データモデルをご覧ください。また、Cloud Firestore データベースの構築方法に関するヒントについては、ソリューションをご覧ください。

データをセキュリティで保護する

Android、Apple、ウェブ クライアントで Cloud Firestore セキュリティ ルールを使用している場合も、サーバーの Identity Access Management(IAM)を使用している場合も、必ず Cloud Firestore と Realtime Database の両方でデータが保護されていることを確認してください。ユーザー認証はどちらのデータベースも Authentication によって処理されるため、Cloud Firestore の使用開始時に Authentication の実装を変更する必要はありません。

考慮すべき主な違い

  • Mobile SDK と Web SDK は Cloud Firestore セキュリティ ルールを使用し、Server SDK は Identity Access Management(IAM)を使用してデータを保護します。
  • ワイルドカードを使用する場合を除き、Cloud Firestore セキュリティ ルールがカスケード式に適用されることはありません。つまり、ワイルドカードを使用しない限り、文書とコレクションにルールは継承されません。
  • Realtime Database の場合とは異なり、データを個別に検証する必要はありません。
  • Cloud Firestore は、クエリを実行する前にルールをチェックして、そのクエリによって返されるすべてのデータに対してユーザーが適切なアクセス権を持っていることを確認します。

履歴データを Cloud Firestore に移動する

データとセキュリティ構造を Cloud Firestore のデータとセキュリティ モデルにマッピングしたら、データを追加できます。アプリを Realtime Database から Cloud Firestore に移動した後に履歴データにクエリを実行する場合は、古いデータのエクスポート データを新しい Cloud Firestore データベースに追加します。アプリで Realtime Database と Cloud Firestore の両方を使用する予定の場合は、この手順を省略します。

新しいデータを古いデータで上書きしないようにするには、最初に履歴データを追加します。次の手順で説明するように、両方のデータベースに新しいデータを同時に追加する場合は、必ず Cloud Functions で Cloud Firestore に追加した新しいデータを優先させてください。

履歴データを Cloud Firestore に移行するには、次の手順を行います。

  1. Realtime Database からデータをエクスポートするか、最新のバックアップを使用します。
    1. Firebase コンソールの [Realtime Database] セクションに移動します。
    2. [データ] タブで、データベースのルートレベルのノードを選択し、メニューから [JSON をエクスポート] を選択します。
  2. Cloud Firestore で新しいデータベースを作成し、データを追加します。

    データを Cloud Firestore に移行する際には、以下の方針を考慮してください。

    • データを移植するカスタム スクリプトを作成する。データベースごとにニーズは異なるため、このスクリプトのテンプレートは提供できませんが、Cloud Firestore のエキスパートが、Slack チャンネルまたは Stack Overflow でお客様のスクリプトをレビューするか、お客様ごとの状況に対応したアドバイスを提供できます。
    • サーバー SDK(Node.js、Java、Python、Go)を使用して Cloud Firestore にデータを直接書き込む。サーバー SDK のセットアップ方法については、スタートガイドをご覧ください。
    • 大規模なデータ移行を迅速に処理するため、一括書き込みを使用し、最大 500 件のオペレーションを 1 つのネットワーク リクエストで送信する。
    • Cloud Firestore レート制限を超えないようにするため、オペレーションをコレクションあたり 500 書き込み/秒に制限する。

Cloud Firestore に新しいデータを追加する

データベース間で一貫性を維持するには、新しいデータを両方のデータベースにリアルタイムで追加します。Cloud Functions を使用して、クライアントが Realtime Database に書き込むたびに Cloud Firestore への書き込みをトリガーします。Cloud Firestore では、履歴データの移行による書き込みよりも、Cloud Functions からの新しいデータを優先させるようにします。

関数を作成して、クライアントが Realtime Database にデータを書き込むたびに Cloud Firestore に新しいデータや変更データが書き込まれるようにします。Cloud Functions の Realtime Database トリガーの詳細をご覧ください。

Cloud Firestore を移行データのプライマリ データベースにする

一部のデータのプライマリ データベースとして Cloud Firestore を使用することに決定した場合は、セットアップしたデータミラーリング機能を確認し、Cloud Firestore セキュリティ ルールを検証してください。

  1. Cloud Functions を使用してデータベース間の一貫性を維持している場合は、両方のデータベースで書き込みオペレーションが重複してループ状態にならないようにしてください。1 つのデータベースに書き込むよう関数を切り替えるか、関数を完全に削除し、Realtime Database を使用するアプリでの移行データの書き込み機能を段階的に停止させます。アプリでのこの処理の方法は、ユーザーや自分のニーズに応じて異なります。

  2. データが適切に保護されていることを確認します。Cloud Firestore セキュリティ ルールまたは IAM 設定を検証します。