Firestore security rules - read allowed only for Story members





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I've read a lot lately about firestore but I'm still struggling with one thing.



I have Story documents in my firestore:



story: {
name: 'James',
members: {
'WeWF34RFD23RF23': 'viewer'
}
}


members property on this document is a map, where key is uid and value is user's role.



I use AngularFireAuth for auth and AngularFirestore to query db.



THE PROBLEM



When I query for documents I get permission error even though I query only for docs I have permissions to read.



  constructor(private db: AngularFirestore, private fAuth: AngularFireAuth) {
this.collection = db.collection<StoryId>('story', ref => ref.where('name', '==', 'James'));
}

ngOnInit() {
this.stories$ = this.collection.snapshotChanges().pipe( ... )
}


There can be multiple James stories and all of them have my uid in its members map. There are also stories that have different name and don't have my uid in it's members map. By this query I want to get all of James stories which results in error but when I query for single document ('story/{story_id}') all works fine.



Here are my security rules



service cloud.firestore {
match /databases/{database}/documents {

match /story/{story} {
allow read: if request.auth.uid in resource.data.members;
allow create;

}
}
}


Maybe the issue is that when AngularFirestore queries for collection it needs access rights to whole collection to return only the values that I can access? If so how can I get only documents that I have access rights to?










share|improve this question































    1















    I've read a lot lately about firestore but I'm still struggling with one thing.



    I have Story documents in my firestore:



    story: {
    name: 'James',
    members: {
    'WeWF34RFD23RF23': 'viewer'
    }
    }


    members property on this document is a map, where key is uid and value is user's role.



    I use AngularFireAuth for auth and AngularFirestore to query db.



    THE PROBLEM



    When I query for documents I get permission error even though I query only for docs I have permissions to read.



      constructor(private db: AngularFirestore, private fAuth: AngularFireAuth) {
    this.collection = db.collection<StoryId>('story', ref => ref.where('name', '==', 'James'));
    }

    ngOnInit() {
    this.stories$ = this.collection.snapshotChanges().pipe( ... )
    }


    There can be multiple James stories and all of them have my uid in its members map. There are also stories that have different name and don't have my uid in it's members map. By this query I want to get all of James stories which results in error but when I query for single document ('story/{story_id}') all works fine.



    Here are my security rules



    service cloud.firestore {
    match /databases/{database}/documents {

    match /story/{story} {
    allow read: if request.auth.uid in resource.data.members;
    allow create;

    }
    }
    }


    Maybe the issue is that when AngularFirestore queries for collection it needs access rights to whole collection to return only the values that I can access? If so how can I get only documents that I have access rights to?










    share|improve this question



























      1












      1








      1








      I've read a lot lately about firestore but I'm still struggling with one thing.



      I have Story documents in my firestore:



      story: {
      name: 'James',
      members: {
      'WeWF34RFD23RF23': 'viewer'
      }
      }


      members property on this document is a map, where key is uid and value is user's role.



      I use AngularFireAuth for auth and AngularFirestore to query db.



      THE PROBLEM



      When I query for documents I get permission error even though I query only for docs I have permissions to read.



        constructor(private db: AngularFirestore, private fAuth: AngularFireAuth) {
      this.collection = db.collection<StoryId>('story', ref => ref.where('name', '==', 'James'));
      }

      ngOnInit() {
      this.stories$ = this.collection.snapshotChanges().pipe( ... )
      }


      There can be multiple James stories and all of them have my uid in its members map. There are also stories that have different name and don't have my uid in it's members map. By this query I want to get all of James stories which results in error but when I query for single document ('story/{story_id}') all works fine.



      Here are my security rules



      service cloud.firestore {
      match /databases/{database}/documents {

      match /story/{story} {
      allow read: if request.auth.uid in resource.data.members;
      allow create;

      }
      }
      }


      Maybe the issue is that when AngularFirestore queries for collection it needs access rights to whole collection to return only the values that I can access? If so how can I get only documents that I have access rights to?










      share|improve this question
















      I've read a lot lately about firestore but I'm still struggling with one thing.



      I have Story documents in my firestore:



      story: {
      name: 'James',
      members: {
      'WeWF34RFD23RF23': 'viewer'
      }
      }


      members property on this document is a map, where key is uid and value is user's role.



      I use AngularFireAuth for auth and AngularFirestore to query db.



      THE PROBLEM



      When I query for documents I get permission error even though I query only for docs I have permissions to read.



        constructor(private db: AngularFirestore, private fAuth: AngularFireAuth) {
      this.collection = db.collection<StoryId>('story', ref => ref.where('name', '==', 'James'));
      }

      ngOnInit() {
      this.stories$ = this.collection.snapshotChanges().pipe( ... )
      }


      There can be multiple James stories and all of them have my uid in its members map. There are also stories that have different name and don't have my uid in it's members map. By this query I want to get all of James stories which results in error but when I query for single document ('story/{story_id}') all works fine.



      Here are my security rules



      service cloud.firestore {
      match /databases/{database}/documents {

      match /story/{story} {
      allow read: if request.auth.uid in resource.data.members;
      allow create;

      }
      }
      }


      Maybe the issue is that when AngularFirestore queries for collection it needs access rights to whole collection to return only the values that I can access? If so how can I get only documents that I have access rights to?







      angular firebase firebase-security






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 10:48







      eso32

















      asked Nov 25 '18 at 10:43









      eso32eso32

      145




      145
























          1 Answer
          1






          active

          oldest

          votes


















          0














          I figured out the solution.



          The problem was If you query only for stories with name = James then firestore will check if you can read (exactly it's called list in firestore) all of documents even though I'm asking only for James.



          What's the solution then?



          The best idea is to keep vulnerable data in subcollection like below



          story: {
          name: 'James',
          superPrivateData: {
          ...here goes subcollection
          }
          }


          But be careful, since map is NOT the same as subcollection.
          More on differences between map and subcollection you can find here



          Hope it will help someone in the future!






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466678%2ffirestore-security-rules-read-allowed-only-for-story-members%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I figured out the solution.



            The problem was If you query only for stories with name = James then firestore will check if you can read (exactly it's called list in firestore) all of documents even though I'm asking only for James.



            What's the solution then?



            The best idea is to keep vulnerable data in subcollection like below



            story: {
            name: 'James',
            superPrivateData: {
            ...here goes subcollection
            }
            }


            But be careful, since map is NOT the same as subcollection.
            More on differences between map and subcollection you can find here



            Hope it will help someone in the future!






            share|improve this answer




























              0














              I figured out the solution.



              The problem was If you query only for stories with name = James then firestore will check if you can read (exactly it's called list in firestore) all of documents even though I'm asking only for James.



              What's the solution then?



              The best idea is to keep vulnerable data in subcollection like below



              story: {
              name: 'James',
              superPrivateData: {
              ...here goes subcollection
              }
              }


              But be careful, since map is NOT the same as subcollection.
              More on differences between map and subcollection you can find here



              Hope it will help someone in the future!






              share|improve this answer


























                0












                0








                0







                I figured out the solution.



                The problem was If you query only for stories with name = James then firestore will check if you can read (exactly it's called list in firestore) all of documents even though I'm asking only for James.



                What's the solution then?



                The best idea is to keep vulnerable data in subcollection like below



                story: {
                name: 'James',
                superPrivateData: {
                ...here goes subcollection
                }
                }


                But be careful, since map is NOT the same as subcollection.
                More on differences between map and subcollection you can find here



                Hope it will help someone in the future!






                share|improve this answer













                I figured out the solution.



                The problem was If you query only for stories with name = James then firestore will check if you can read (exactly it's called list in firestore) all of documents even though I'm asking only for James.



                What's the solution then?



                The best idea is to keep vulnerable data in subcollection like below



                story: {
                name: 'James',
                superPrivateData: {
                ...here goes subcollection
                }
                }


                But be careful, since map is NOT the same as subcollection.
                More on differences between map and subcollection you can find here



                Hope it will help someone in the future!







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 28 '18 at 22:16









                eso32eso32

                145




                145
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466678%2ffirestore-security-rules-read-allowed-only-for-story-members%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()