我在Firestore中实施食谱书,其中每个用户都能够看到所有用户创建的所有食谱,但只允许食谱的原始作者编辑或删除食谱。任何用户也可以创建新配方。
我的问题是我无法将子集合设置为" listen"在subcollections parentdocument的字段上。
每个食谱文档包含三件事。一个名为name
的字段,其中存储了食谱的名称,一个名为creatorUID
的字段,其中存储了创建者uid的request.auth.uid
,另一个名为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 = permission-denied]:权限丢失或不足。 FirebaseError:权限丢失或不足。
这些电话来自Angular客户及其官方图书馆。
答案 0 :(得分:23)
规则不会级联,因此您需要对规则捕获的文档执行所需的任何检查。
一般来说,{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;
}
}
}
}
答案 1 :(得分:1)
基于Dan的答案,您应该能够通过将creatorUID添加到子集合文档中来减少数据库中对子集合update
和delete
的读取次数。
您必须将create
限制为仅创建者,并确保已设置creatorUID。这是我对丹的规则的修改:
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 update, delete: if resource.data.creatorUID == request.auth.uid;
allow create: if recipeData().creatorUID == request.auth.uid
&& request.resource.data.creatorUID == request.auth.uid;
}
}
}
}
答案 2 :(得分:0)
Dan的答案非常有效!仅供参考,在我的情况下,我只需要根父文档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';
}
}
}
}