0
votes

i have a firestore db and it has some collection. each collection has some documents and the document will have a field called userId. This userId is the thing i want to match when i write the security rule. My data looks like this. look at the users collection one particular object. enter image description here

Now i want the security rule something like this:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{User}{
      allow read, write:  if resource.data.userId == request.auth.uid;
    }
  }
}

when i make a call to read the data:

import firestore from '@react-native-firebase/firestore';
console.log(`made db call to update menu for userid ${user.uid}`);
    try{
    var querySnapshot = await firestore().collection('Users').get();
    console.log(querySnapshot.size);

    querySnapshot.forEach(documentSnapshot => {
      console.log('snapshot ID: ', documentSnapshot.id, documentSnapshot.data());
    });

here is the error i get along with the logged userid used: [Fri Dec 11 2020 15:53:22.649] LOG made db call to update menu for userid CKKMUujnojNiUGO7z8FHxtnquQ53 [Fri Dec 11 2020 15:53:22.808] LOG [Error: [firestore/permission-denied] The caller does not have permission to execute the specified operation.]

i get this error:[Error: [firestore/permission-denied] The caller does not have permission to execute the specified operation.] i am basically not able to put any condition that relies on resource.data. i hardcoded id once and put request.auth.uid =="hard coded id" and that also worked. i think somehow resource.data.userId is not resoving although it looks correct to me.

1
"when i make a call to read the data" Please edit your question to include this code. Also make sure to show proof that it meets the requirements in your security rules. For example: log the UID right before the call, and include that code and its output in the question. - Frank van Puffelen
@FrankvanPuffelen made the edits as per your suggestions. also if you keep reading my question i mentioned that when i hardcode the rule by saying request.auth.uid == "id i know", it works which proves that id is passed from request correctly. - Manish Shukla

1 Answers

0
votes

It's important to realize that Firestore security rules are not filters. Be sure to read that linked documentation. Security rules will not filter the documents to match only what a user is allowed to read.

Your query is demanding all of the documents in Users:

firestore().collection('Users').get();

However, your rules insist that a user must only request documents where their UID is in the userId field of the document:

allow read, write:  if resource.data.userId == request.auth.uid;

You can make your query match the requirements of the rules by adding a filter on the userId field:

firestore()
    .collection('Users')
    .where('userId', '==', user.uid)
    .get();