私のチームは最近これについて話し合っており、実際の/意図された動作を確実に判断できないようです:
次のようなセキュリティルールがある場合:
match /categories/{document=**} {
allow update: if request.auth.uid != null
&& request.resource.data.firstName is string
&& request.resource.data.lastName is string;
}
そして、次のデータを使用して、フロントエンドから/ categories /への更新ステートメントを作成します。
{
firstName: 'A valid firstName'
}
次に、セキュリティルールは合格または不合格になるはずですか?
リファレンスドキュメント では、
開発者が提供するデータは、フィールドと値を含むマップであるrequest.resource.dataに表示されます。リソースに存在する、リクエストで提供されていないフィールドは、request.resource.dataに追加されます
関連する質問:
{age: 28}
質問3と詳細(スキーマの質問)次のようなモデルがあるとします。
interface Category {
firstName: string;
lastName: string;
age?: int;
groupId?: string;
}
次のようなセキュリティルールを作成します。
match /categories/{document=**} {
allow update: if request.auth.uid != null
&& request.resource.data.firstName is string
&& request.resource.data.lastName is string;
&& request.resource.data.age is int;
&& request.resource.data.groupId is string;
}
これらのシナリオのどれもなしは、オプションのプロパティとうまく適合します。すべてのプロパティを提供する必要がある場合(シナリオ1のように)は、実際にはオプションのプロパティではないためです。そして、シナリオ2のようにそれらを提供しないと、失敗します。
たぶん私はここで何か、Firestoreに書き込まれているオプションのプロパティでデータを検証する方法の基本的なガイドを見逃しています
次のようなオプションパラメータのセキュリティルール:
match /categories/{document=**} {
allow update: if request.auth.uid != null
&& request.resource.data.firstName is string
&& request.resource.data.lastName is string;
&& request.resource.data.age is int; // ignore if NOT provided
&& request.resource.data.groupId is string; // ignore if NOT provided
}
次に、セキュリティルールは合格または不合格になるはずですか?
更新されるドキュメントにすでにlastName
フィールドがあり、このフィールドがstring
である場合、その更新は成功します。 (request.auth.uid != null
がtrueを返すように、認証中にこの更新を実行していると想定しています)
関連する質問への回答:
firstName
およびlastName
セットが含まれている場合、age
フィールドの追加は成功します。ルールは、これら2つの値が文字列であるかどうかのみをチェックすることに注意してください。文書に2つを超えるフィールドを含めることができないことは指定していません。更新:
更新された質問3からわかったことは、ユーザーが姓と名の両方を入力した場合にのみドキュメントを更新することです。 ageとgroupIdはオプションです。
これを行うには、request.resource.data.firstName
を使用して、このresource.data.firstName != request.resource.data.firstName
がデータベースにすでに存在しないかどうかを確認できます。したがって、セキュリティルールは次のようになります。
match /categories/{document=**} {
allow update: if request.auth.uid != null
&& (request.resource.data.firstName is string && resource.data.firstName != request.resource.data.firstName)
&& (request.resource.data.lastName is string && resource.data.firstName != request.resource.data.firstName)
&& request.resource.data.age is int
&& request.resource.data.groupId is string
}
これらのルールにより、このデータでの更新は失敗します:
{
firstName: 'A valid firstName'
}
これら3つは成功しますが、
{
firstName: 'A valid firstName',
lastName: 'A valid lastName'
}
{
firstName: 'A valid firstName',
lastName: 'A valid lastName',
age: 20
}
{
firstName: 'A valid firstName',
lastName: 'A valid lastName',
age: 20,
groupId: 'groupId'
}
Update 2:age
およびgroupId
をオプションのフィールドとして使用するには、OR演算子を使用しますhasAll()
関数を使用して、リクエストに次のフィールドがあるかどうかを確認します。
match /categories/{document=**} {
allow update: if request.auth.uid != null
&& (request.resource.data.firstName is string && resource.data.firstName != request.resource.data.firstName)
&& (request.resource.data.lastName is string && resource.data.firstName != request.resource.data.firstName)
|| (request.resource.data.keys().hasAll(['age']) && request.resource.data.age is int)
|| (request.resource.data.keys().hasAll(['groupId']) && request.resource.data.groupId is string)
}