Firebase Summit のすべての発表内容に目を通し、Firebase を活用してアプリ開発を加速し、自信を持ってアプリを実行できる方法をご確認ください。 詳細

CloudFirestoreのセキュリティルールの構造化

Cloud Firestore セキュリティ ルールを使用すると、データベース内のドキュメントとコレクションへのアクセスを制御できます。柔軟なルール構文により、データベース全体へのすべての書き込みから特定のドキュメントに対する操作まで、あらゆるものに一致するルールを作成できます。

このガイドでは、セキュリティ ルールの基本的な構文と構造について説明します。この構文をセキュリティ ルール条件と組み合わせて、完全なルールセットを作成します。

サービスとデータベースの宣言

Cloud Firestore セキュリティ ルールは、常に次の宣言で始まります。

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

service cloud.firestore宣言は、ルールの範囲を Cloud Firestore に限定し、Cloud Firestore セキュリティ ルールと Cloud Storage などの他のプロダクトのルールとの間の競合を防ぎます。

match /databases/{database}/documents宣言は、ルールがプロジェクト内の任意の Cloud Firestore データベースと一致する必要があることを指定します。現在、各プロジェクトには(default)という名前の単一のデータベースしかありません。

基本的な読み取り/書き込みルール

基本的なルールは、ドキュメント パスを指定するmatchステートメントと、指定されたデータの読み取りが許可される場合の詳細を示すallow式で構成されます。

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

すべての match ステートメントは、コレクションではなく、ドキュメントを指す必要があります。 match ステートメントは、 match /cities/SFのように特定のドキュメントを指すか、またはmatch /cities/{city}のようにワイルドカードを使用して指定されたパス内の任意のドキュメントを指すことができます。

上記の例では、match ステートメントで{city}ワイルドカード構文を使用しています。これは、規則が/cities/SF/cities/NYCなどのcitiesコレクション内のすべてのドキュメントに適用されることを意味します。 match ステートメントのallow式が評価されると、 city変数はSFNYCなどの都市ドキュメント名に解決されます。

きめ細かい操作

場合によっては、 readwriteをより細かい操作に分割すると便利です。たとえば、アプリでは、ドキュメントの削除時とは異なる条件をドキュメントの作成時に適用したい場合があります。または、単一のドキュメントの読み取りを許可し、大きなクエリを拒否することもできます。

readルールはgetlistに分割でき、 writeルールはcreateupdate 、およびdeleteに分割できます。

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

階層データ

Cloud Firestore のデータはドキュメントのコレクションに編成され、各ドキュメントはサブコレクションを通じて階層を拡張できます。セキュリティ ルールが階層データとどのように相互作用するかを理解することが重要です。

citiesコレクションの各ドキュメントにlandmarksサブコレクションが含まれている状況を考えてみましょう。セキュリティ ルールは一致したパスにのみ適用されるため、 citiesコレクションで定義されたアクセス制御はlandmarksサブコレクションには適用されません。代わりに、サブコレクションへのアクセスを制御する明示的なルールを記述します。

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

matchステートメントをネストする場合、内側のmatchステートメントのパスは常に、外側のmatchステートメントのパスに対して相対的です。したがって、次のルールセットは同等です。

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

再帰ワイルドカード

ルールを任意の深い階層に適用する場合は、再帰ワイルドカード構文{name=**}を使用します。例えば:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

再帰的なワイルドカード構文を使用すると、ドキュメントが深くネストされたサブコレクションにある場合でも、ワイルドカード変数には一致するパス セグメント全体が含まれます。たとえば、上記のルールは/cities/SF/landmarks/coit_towerにあるドキュメントに一致し、 document変数の値はSF/landmarks/coit_towerになります。

ただし、再帰ワイルドカードの動作はルールのバージョンに依存することに注意してください。

バージョン 1

セキュリティ ルールは、デフォルトでバージョン 1 を使用します。バージョン 1 では、再帰ワイルドカードは 1 つ以上のパス項目に一致します。空のパスには一致しないため、 match /cities/{city}/{document=**}はサブコレクション内のドキュメントに一致しますが、 citiesコレクション内のドキュメントには一致しません。一方、 match /cities/{document=**}はサブコレクション内の両方のドキュメントに一致しますcitiesコレクションとサブコレクション。

再帰ワイルドカードは、match ステートメントの最後にある必要があります。

バージョン 2

バージョン 2 のセキュリティ ルールでは、再帰ワイルドカードは 0 個以上のパス項目に一致します。 match/cities/{city}/{document=**}は、すべてのサブコレクション内のドキュメントと、 citiesコレクション内のドキュメントに一致します。

rules_version = '2';を追加して、バージョン 2 にオプトインする必要があります。あなたのセキュリティルールの一番上に:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

match ステートメントごとに再帰ワイルドカードを最大 1 つ使用できますが、バージョン 2 では、このワイルドカードを match ステートメントの任意の場所に配置できます。例えば:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

コレクション グループ クエリを使用する場合は、バージョン 2 を使用する必要があります。コレクション グループ クエリの保護を参照してください。

match ステートメントの重複

ドキュメントが複数のmatchステートメントに一致する可能性があります。複数のallow式がリクエストに一致する場合、いずれかの条件がtrueであればアクセスが許可されます。

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

上記の例では、最初のルールは常にfalseですが、2 番目のルールは常にtrueであるため、 citiesコレクションに対するすべての読み取りと書き込みが許可されます。

セキュリティ ルールの制限

セキュリティ ルールを操作するときは、次の制限に注意してください。

リミット詳細
リクエストあたりのexists()get() 、およびgetAfter()呼び出しの最大数
  • 単一ドキュメント リクエストとクエリ リクエストの場合は 10。
  • 複数ドキュメントの読み取り、トランザクション、およびバッチ書き込みの場合は 20。以前の制限である 10 も、各操作に適用されます。

    たとえば、3 つの書き込み操作を含むバッチ書き込み要求を作成し、セキュリティ ルールで 2 つのドキュメント アクセス呼び出しを使用して各書き込みを検証するとします。この場合、各書き込みは 10 回のアクセス呼び出しのうち 2 回を使用し、バッチ化された書き込み要求は 20 回のアクセス呼び出しのうち 6 回を使用します。

いずれかの制限を超えると、許可拒否エラーが発生します。

一部のドキュメント アクセス呼び出しはキャッシュされる可能性があり、キャッシュされた呼び出しは制限に対してカウントされません。

ネストされたmatchステートメントの最大深さ10
ネストされたmatchステートメントのセット内で許可される、パス セグメント内の最大パス長100
ネストされたmatchステートメントのセット内で許可されるパス キャプチャ変数の最大数20
関数呼び出しの最大深度20
関数の引数の最大数7
関数あたりのlet変数バインディングの最大数10
再帰的または循環的な関数呼び出しの最大数0 (許可されていません)
リクエストごとに評価される式の最大数1,000
ルールセットの最大サイズルールセットは、次の 2 つのサイズ制限に従う必要があります。
  • Firebase コンソールまたはfirebase deployを使用して CLI から発行されるルールセット テキスト ソースのサイズに対する 256 KB の制限。
  • Firebase がソースを処理し、バックエンドでアクティブにしたときに生じる、コンパイル済みルールセットのサイズに対する 250 KB の制限。

次のステップ