先日に引き続き今日も Firestore
のセキュリティルール について書いていきたいと思います👀
今回はタイトルの通り、Firestore
のドキュメントに書き込めるフィールドのバリデーションを行っていきたいと思います。
それではやっていく
ということで、「こんな時はこうする!」的なことをつらつらと書いてみます。
指定したフィールド以外書き込めないようにしたい!
match /hoge/{hogeId} { allow create: if request.resource.data.keys().hasOnly(['name', 'age', 'createdAt', 'updatedAt']); }
hasOnly()
メソッドは、リスト内のすべての要素が引数リスト内の要素に存在するかどうかを Boolean
で返します。
特定のフィールドを必須にしたい!
match /hoge/{hogeId} { allow create: if request.resource.data.keys().hasAll(['name', 'age']); }
hasAll()
メソッドは、リスト内に引数リスト内の要素がすべて存在するかどうかを Boolean
で返します。
あるフィールドの値の型を指定したい!
match /hoge/{hogeId} { allow create: if request.resource.data.name is string; }
ちなみに data
に name
がない場合はリクエスト全体が失敗してしまうので、フィールドが data
に含まれない可能性ある場合は Map
の get()
メソッドを使ってデフォルト値を設置してあげます。ちなみにこの get()
メソッドはあくまで Map
のインスタンスメソッドであり、セキュリティルール標準メソッドの get()
とは異なります。
match /hoge/{hogeId} { allow create: if request.resource.data.get('name', 'default') is string; }
セキュリティルール言語については下記を参照してください。
指定したフィールド以外更新できないようにしたい!
match /hoge/{hogeId} { allow update: if request.resource.data.diff(resource.data).affectedKeys().hasOnly(['name']); }
こちらに関しては公式ドキュメントにも詳しく記載されているのでリンクを載せておきます✍️
特定のフィールドへのアクセスを制御する | Firestore | Google Cloud
関数を定義
今回紹介したバリデーションの内、ある程度使用頻度の多くなりそうなものは関数に切り出しておくと便利です。
// Create の際に必須項目とオプショナル項目を指定する function verifyCreateFields(required, optional) { let allAllowedFields = required.concat(optional); return request.resource.data.keys().hasAll(required) && request.resource.data.keys().hasOnly(allAllowedFields); } // Update の際に更新できるフィールドを限定する function verifyUpdateFields(fields) { return request.resource.data.diff(resource.data).affectedKeys().hasOnly(fields); } // Create の際にドキュメント内の Map データの必須項目とオプショナル項目を指定する function verifyAnyCreateFields(data, required, optional) { let allAllowedFields = required.concat(optional); return data.keys().hasAll(required) && data.keys().hasOnly(allAllowedFields); } // Update の際にドキュメント内の Map データの更新できるフィールドを限定する function verifyAnyUpdateFields(data, previousData, fields) { return data.diff(previousData).affectedKeys().hasOnly(fields); }
という感じで本日も以上になります🍺
参考
- https://cloud.google.com/firestore/docs/security/rules-fields?hl=ja
- https://firebase.google.com/docs/rules/rules-language
- https://firebase.google.com/docs/reference/rules