Access parent documents field in Firestore rules

孤人 提交于 2019-12-09 04:46:23

问题


I'm implementing a recipe book in Firestore where every user is able to see all the recipes all users created but only the original author of the recipe is allowed to edit or delete the recipe. Any user is also allowed to create a new recipe.

My problem is that I am unable to setup the permissions a subcollection to "listen" on a field of the subcollections parentdocument.

Each recipe document contains three things. A field called name where the name of the recipe is stored, a field called creatorUID where the request.auth.uid of the creators uid is stored and a subcollection called ingredients containing documents with some random fields.

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;
        }
    }
  }
}

The problem is that with these rules it only works to create the recipe document. The subcollection and it's documents are not created since the db says

FirebaseError: [code=permission-denied]: Missing or insufficient permissions. FirebaseError: Missing or insufficient permissions.

The calls is made from Angular client and it's official library.


回答1:


Rules don't cascade, so you'll need to perform whatever checks you need for the document being captured by the Rules.

Generally speaking, {x=**} rules are more often a mistake and the usage of =** only for extremely specific use cases.

From your question, I'm assuming your data mode is something like this:

/ListofRecipes/{recipe_document}/List/{list_document}

In this case, you'll need your Rules to be configured something like this:

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;
        }
    }
  }
}



回答2:


Dan's answer above works great! Just for reference, in my case I only needed the root parent document ID, you can use the variable from the match statement above the nested one, like this:

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';
        }
    }
  }
}


来源:https://stackoverflow.com/questions/48439322/access-parent-documents-field-in-firestore-rules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!