访问Firestore规则中的父文档字段

Pay*_*erl 8 firebase firebase-security angularfire2 google-cloud-firestore

我正在Firestore中实现一个食谱书,其中每个用户都能够看到所有用户创建的所有食谱,但只允许食谱的原始作者编辑或删除食谱.任何用户也可以创建新配方.

我的问题是我无法在子集合父文档的字段上设置子集的权限以"监听".

每个食谱文档包含三件事.称为一个字段name存储配方的名称,其中,一个叫场creatorUID,其中request.auth.uid创作者的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;
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是,使用这些规则它只能用于创建配方文档.db表示,子集合及其文档不会创建

FirebaseError:[code = permission-denied]:权限丢失或不足.FirebaseError:权限丢失或不足.

这些调用来自Angular客户端及其官方库.

Dan*_*ath 32

规则不会级联,因此您需要对规则捕获的文档执行所需的任何检查.

一般来说,{x=**}规则通常是一个错误,并且=**仅用于极其特定的用例.

从您的问题来看,我假设您的数据模式是这样的:

/ListofRecipes/{recipe_document}/List/{list_document}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要将您的规则配置为以下内容:

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;
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Payerl这是一个很好的解决方案,但是,有一个问题您应该非常清楚。每次运行“recipeData()”函数时,它都会根据您计费的读取次数进行计数。因此,如果经常写入该子集合,它将很快变得超级昂贵。 (7认同)