Chris
Chris

Reputation: 2314

Firebase Security Rules restrict access to sub collections

This is my Database-Structure:

users (collection) -> user-docs (uid) -> wishlists (collection) -> wishlist-docs -> wünsche -> wünsche-docs

users should be readable for everyone, even unauthorized users. Everything else should be readable/writable for authorized users only.

This is what I tried:

service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
  allow write: if request.auth != null;
}
match /{users} {
    allow read;
}
match /{users}/documents/{allSubcollections=**} {
    allow read: if request.auth != null
}
}
}

However this is not working because there is something messed up with read. I can not read anything. What am I doing wrong here?

Edit:

This is how I want to access users:

//MARK: check username
static func checkUsername(field: String, completion: @escaping (Bool) -> Void) {
    
    let db = Firestore.firestore()
    let collectionRef = db.collection(Keys.users)
    
    collectionRef.whereField(Keys.username, isEqualTo: field).getDocuments { (snapshot, err) in
        if let err = err {
            print("Error getting document: \(err)")
        } else if (snapshot?.isEmpty)! {
            completion(false)
        } else {
            for document in (snapshot?.documents)! {
                if document.data()[Keys.username] != nil {
                    completion(true)
                }
            }
        }
    }
}

This should also work if the user is not authorized. Everything else should be restricted to authorized users only.

Upvotes: 0

Views: 172

Answers (1)

Rafael Lemos
Rafael Lemos

Reputation: 5829

You are using a {users} to refer to your collection name, that is incorrect, you need to simply use it without the brackets since those are used as wildcards in your rules, eg. you can use /users/{userId} to match the userId in the rules.

Also I would not recommend using a rule for all collections at the beggining of your rules, as it's a bit error prone. That being said, the following rules should work in your case:

service cloud.firestore {
    match /databases/{database}/documents {
        match /users/{userId} {
            allow read;
            allow write: if request.auth != null;
        }
        match /users/{userId}/wishlists/{restOfPath=**} {
            allow read,write: if request.auth != null;
        }
    }
}

Try it out and let me know if it's still not working. Also, check this video tutorial for Firebase Rules, there is a lot of useful information there.

Upvotes: 1

Related Questions