0
votes

I'm trying to set up Cloud Firestore security rules so that document access is only granted to a user who's ID matches the document ID. Firebase Authentication is being used to authenticate the user and name the document with the user-specific ID. The documents are stored within the "Users" collection.

Here are my rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;
    }
  }
}

Here is the code that makes the query to the database:

     func loadData () {
              
              //For Database
              let userID = Auth.auth().currentUser?.uid
              let db = Firestore.firestore()
              
              
              db.collection("Users/\(userID!)/Info").document("Info").getDocument { (document, error) in
                  
                  if error == nil {
                      //No error, check that document exists
                      
                      if document != nil && document!.exists {
                          
                          //Load the user data to the view controller
                              
                      } else {
                          //Show the error which has occured
                          print("Document does not exist")
                      }
                  } else {
                    //Show the error which has occured
                    print("Error loading user data")
                  
                  }
        }
    }

I'm struggling to understand the problem as other threads I have looked at which contain exactly the same code, do not work. Firebase simulator gives me the error: "Simulated read denied" with "Access denied for this match". In Xcode, I get the error message: "[Firebase/Firestore][I-FST000001] Listen for query at Users/DB9wtqM9h0OO1paMjNWAdsF4EgX2 failed: Missing or insufficient permissions." Hardcoding the UID does work, so I'm assuming it is something to do with the file path.

Please help, thank you!

1
The rules seems ok. Show your query, for which you got the "Missing or insufficient permissions" error.hkchakladar
Please edit the question to show the specific code that isn't working the way you expect. Security rules don't have any meaning unless they apply to queries that should be allowed or rejected. We should be able to reproduce the issue based on what you give in the question.Doug Stevenson
Question edited as requestedcarloregian

1 Answers

0
votes

Your rules actually don't apply at all to the query you're showing. The rules are only going to match documents immediately within the Users collection, such as "/Users/abc". Your query is accessing a subcollection organized under documents in Users.

If you want to match document with the ID "Info" in any subcollection called also "Info" nested under "Users", your rule should look like this:

    match /Users/{userId}/Info/Info {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;
    }

Notice how the path of the document is fully matched to the document in the query.

You might also want to read about recursive wildcards if you want to protect documents in any subcollection under a main collection.