0
votes

Having a little problem with a Firebase Rule.

Here is a sample record: Sample Image of Record

Here is my rule:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /question/{questionId}{
      allow read : if (request.auth.token.email_verified == true) &&
       (request.auth.uid == resource.data.quid);
    }
  }
}

This fails with:

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

However, when changing (request.auth.uid == resource.data.quid); to (request.auth.uid == 'gTEsGw3cUlaCswmVwpgdSzEd1TW2'); it works fine. I can also match against email address just fine. Just not the uid to quid field.

Thoughts?

If it matters, this is the query in my code:

const showQuestions = () => {db.collection('question').where("email", "==", userObject.email).onSnapshot( data => {
        questions = data.docs;
    })
}
1
Security rules by themselves don't do anything. They are only active when an app makes a query. Please edit the question to show the code that makes the query, so we can see what the rules are actively working with. - Doug Stevenson

1 Answers

1
votes

Your query does not match your rules. Your rule absolutely requires that the user must only query for specific documents where their UID matches quid field of the document. However, your query doesn't put any requirements on the quid field. It's important to know that Firestore security rules are not filters, and they will not allow a query where there is any possibility of matching a document that does not satisfy the rules as written.

In order to get your query to work, it must specify a filter on the quid field that matches the requirements of the rule.

db.collection('question')
    .where("email", "==", userObject.email)
    .where("quid", "==", uid)

where uid is the UID of the currently signed in user (e.g. firebase.auth().currentUser.uid).