私はFirestoreにレシピブックを実装しています。このブックでは、すべてのユーザーが作成したすべてのレシピを表示できますが、レシピの編集または削除はレシピの元の作成者のみが許可されています。すべてのユーザーが新しいレシピを作成することもできます。
私の問題は、サブコレクションの親ドキュメントのフィールドで「リッスン」するためのサブコレクションのアクセス許可を設定できないことです。
各レシピドキュメントには3つのものが含まれています。レシピの名前が格納されているname
というフィールド、作成者uidのrequest.auth.uid
が格納されているcreatorUID
というフィールド、およびingredients
というサブコレクションいくつかのランダムなフィールドを持つドキュメントが含まれています。
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth != null;
}
match /ListOfRecipes/{recipe} {
allow read, create: if isSignedIn();
allow update, delete: if resource.data.creatorUID == request.auth.uid;
match /{list=**} {
allow read: if isSignedIn();
// Should return true if recipe.creatorUID has same value as request.auth.uid
allow write: if recipe.creatorUID == request.auth.uid;
}
}
}
}
問題は、これらのルールでは、レシピドキュメントの作成にしか機能しないことです。サブコレクションとそのドキュメントは、dbが言うので作成されません
FirebaseError:[code = permit-denied]:権限がないか不十分です。 FirebaseError:権限がないか不十分です。
呼び出しはAngularクライアントとその公式ライブラリから行われます。
ルールはカスケードされないため、ルールによってキャプチャされるドキュメントに必要なチェックを実行する必要があります。
一般的に言って、{x=**}
ルールは間違いであることが多く、=**
の使用法は非常に特殊な使用例に限られます。
あなたの質問から、私はあなたのデータモードが次のようなものだと思います:
/ListofRecipes/{recipe_document}/List/{list_document}
この場合、ルールを次のように構成する必要があります。
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth != null;
}
match /ListOfRecipes/{recipe} {
allow read, create: if isSignedIn();
allow update, delete: if resource.data.creatorUID == request.auth.uid;
function recipeData() {
return get(/databases/$(database)/documents/ListOfRecipes/$(recipe)).data
}
match /List/{list} {
allow read: if isSignedIn();
allow write: if recipeData().creatorUID == request.auth.uid;
}
}
}
}
上記のダンの答えはうまくいきます!参考までに、私の場合はルートの親ドキュメントIDのみが必要でした。次のように、ネストされたステートメントの上にあるmatchステートメントの変数を使用できます。
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth != null;
}
match /ListOfRecipes/{recipeID} {
allow read, create: if isSignedIn();
allow update, delete: if resource.data.creatorUID == request.auth.uid;
match /List/{list} {
allow read: if isSignedIn();
allow write: if recipeID == 'XXXXX';
}
}
}
}