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
変数はSF
やNYC
などの都市ドキュメント名に解決されます。
きめ細かい操作
場合によっては、 read
とwrite
をより細かい操作に分割すると便利です。たとえば、アプリでは、ドキュメントの削除時とは異なる条件をドキュメントの作成時に適用したい場合があります。または、単一のドキュメントの読み取りを許可し、大きなクエリを拒否することもできます。
read
ルールはget
とlist
に分割でき、 write
ルールはcreate
、 update
、および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() 呼び出しの最大数 |
いずれかの制限を超えると、許可拒否エラーが発生します。 一部のドキュメント アクセス呼び出しはキャッシュされる可能性があり、キャッシュされた呼び出しは制限に対してカウントされません。 |
ネストされたmatch ステートメントの最大深さ | 10 |
ネストされたmatch ステートメントのセット内で許可される、パス セグメント内の最大パス長 | 100 |
ネストされたmatch ステートメントのセット内で許可されるパス キャプチャ変数の最大数 | 20 |
関数呼び出しの最大深度 | 20 |
関数の引数の最大数 | 7 |
関数あたりのlet 変数バインディングの最大数 | 10 |
再帰的または循環的な関数呼び出しの最大数 | 0 (許可されていません) |
リクエストごとに評価される式の最大数 | 1,000 |
ルールセットの最大サイズ | ルールセットは、次の 2 つのサイズ制限に従う必要があります。
|
次のステップ
- カスタム セキュリティ ルールの条件を記述します。
- セキュリティ ルール リファレンスをお読みください。