Here is my structured data:
Users
- w34rj3d9d2383
- name
- email
- items (sub-collection)
- dj23jd23wkjdkl
- name
- notes
- createdBy
- 4ru328rjwiodj2309
- name
- notes
- createdBy
Using the rules below, I am able to specify the userId and itemId to successfully subscribe to an individual item in the items subcollection for the authenticated user. I am also able to fetch all the items for the specified user if I don't apply a predicate.
The problem is that when I attempt to apply a predicate to the collection (see below), it doesn't return anything.
let path = "users/w34rj3d9d2383/items"
let predicate = NSPredicate(format: "SELF.name CONTAINS %@", name)
let collectionReference = Firestore.firestore().collection(path).filter(using: predicate)
collectionReference.addSnapshotListener(includeMetadataChanges: false) { querySnapshot, error in
//...
}
Here are my security rules. How can I query over my sub collection?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
match /users/{userId}/{document=**}{
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
Update 1: I tried the following, but it still shows permission issues:
- Updating my reference to collection group:
let collectionReference = Firestore.firestore().collectionGroup("items").filter(using: predicate)
- Adding this to my rules
match /{path=**}/items/{itemId} {
allow list: if request.auth.uid == resource.data.createdBy;
allow get: if request.auth.uid == resource.data.createdBy;
}
Update 2: I got a query going, and the following rule working:
match /{path=**}/items/{itemId} {
allow read, write: if request.auth != null;
}
This means I can fetch all items anytime I do a collection group query without a predicate. However, I want to only return items where the resource.data.createdBy value matches request.auth.uid. However, when I add this check it says resource is null.