Firebase Realtime Database で Cloud Firestore を使用する

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

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

Cloud Firestore へのデータ移動

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

  1. データ構造とセキュリティ ルールを Realtime Database から Cloud Firestore にマッピングします。Realtime DatabaseCloud 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 DatabaseCloud Firestore の請求額は異なります。多くの場合、Cloud FirestoreRealtime Database よりも費用がかかります。多数の小規模オペレーションを使用している場合は、その違いが特に顕著に表れます。データベースのオペレーション数を減らし、不要な書き込みを避けることを検討してください。Realtime DatabaseCloud Firestore課金の違いについて詳しくご覧ください。

実施時におすすめの方法

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

たとえば、ユーザーが世界中の都市の名所を見つけるのに役立つ、都市ガイドアプリを作っているとします。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 Security Rules を使用している場合も、サーバーの Identity Access Management(IAM)を使用している場合も、必ず Cloud FirestoreRealtime Database の両方でデータが保護されていることを確認してください。ユーザー認証はどちらのデータベースも Authentication によって処理されるため、Cloud Firestore の使用開始時に Authentication の実装を変更する必要はありません。

考慮すべき主な違い

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

過去のデータを Cloud Firestore に移動する

データとセキュリティ構造を Cloud Firestore のデータとセキュリティ モデルにマッピングしたら、データを追加できます。アプリを Realtime Database から Cloud Firestore に移動した後に履歴データにクエリを実行する場合は、古いデータのエクスポートを新しい Cloud Firestore データベースに追加します。アプリで Realtime DatabaseCloud 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 FunctionsRealtime Database トリガーをご覧ください。

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

一部のデータのプライマリ データベースとして Cloud Firestore を使用することに決定した場合は、セットアップしたデータミラーリング機能を説明して、Cloud Firestore Security Rules を検証するようにしてください。

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

  2. データが適切に保護されていることを確認します。Cloud Firestore Security Rules または IAM の設定を検証します。