Nienormalny_
Nienormalny_

Reputation: 470

Getting document data from collections - with firestore security rules

I have a problem with creating rules in firestore.

This is my example: collection "users" -> many docs -> not every doc has inside, the subcollection with name "recipes". If subcollection "recipes" exists then it has docs with some data. One of them is "public" with type of boolean.

My problem: I want to get all recipes from all users, if condition of "public" is true.

Im stack at rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth != null && request.auth.uid == userId;
      allow write: if request.auth != null && request.auth.uid == userId;
      match /recipes/{recipeId} {
            allow read: if resource.data.public == "true";
        }
    }
  }
}

enter image description here

And it shows me: Error: simulator.rules line [9], column [21]. Null value error.

In this case, how should I get/call this data with clean javascript? If i just get some scripts like firebase.firestore() or firebase.auth().

Upvotes: 0

Views: 1158

Answers (2)

Nienormalny_
Nienormalny_

Reputation: 470

for those they are searching for solution. I found one! let me explain:

  1. I found https://firebase.google.com/docs/firestore/security/rules-query document about query rules.
  2. Then i decide to use firebase.firestore().collectionGroup('recipes').get().then(...)...
  3. My security code it looks like:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{path=**}/recipes/{document} {
      allow read: if resource.data.public == true;
    }
  }
}
  1. My javascript call, looks like:
firebase.firestore().collectionGroup('recipes').where('public', '==', true).get().then(recipes => {
  recipes.forEach(doc => {
    console.log(doc.data());
  })
});
  1. After that i could see error in my console.log: AILED_PRECONDITION: The query requires an index. You can create it here or something familiar with link!
  2. I clicked the link and then accepted indexing settings for collectionGroup.
  3. You can find it here as well: enter image description here

Sorry for my bad english and Polski język, but i think i got this right! So it helped me to get onlz public recipes!

Upvotes: 2

ThienLD
ThienLD

Reputation: 741

You can't filter result with security rules. Security rules will block your request if there is one or more document violating the rules. What you need is collection group queries. For example:

const querySnapshot = await db.collectionGroup('recipes').where('public', '==', true).get();
    querySnapshot.forEach((doc) => {
        console.log(doc.id, ' => ', doc.data());
});

Upvotes: 1

Related Questions