As I understand it, Firestore does not allow queries within fields of type array, which is a shame. Therefore, if you want to be able to query the contents of an array you have to set up a field as an object type and then set the fields like a map, this is called a nested map. I want to have a map where the key is the ID of another user. Therefore, the database structure is:
database
users
{userId}
friends
userId1: true
userId2: true
The 'userId1' and 'userId2' field names will vary depending on the userId of the person listed as a friend.
The question is, how do I write my security rule so I can find my documents (via my {userId}) and the documents of other users where my {userId} is a field in the 'friends' object of the other user's document?
I guess it needs to be something like..
match /users/{userId} {
allow read, update, delete: if resource.data.userId == request.auth.uid;
allow read: if resource.data.friends.{userId} == true;
}
But of course this does not work because you cannot seem to use the variable {userId} to name the field that you want to perform a test on. So, if this cannot be done, what is a way to search for documents and have my {userId} stored somehow in someone else's document?
Edit
Well, I think I have the rules determined (see below). However, when trying to test these rules I can't seem to write a Swift call to retrieve data based on that friends object. My Swift call is:
db.collection("users").whereField(FieldPath(["friends.\(userId)"]), isEqualTo: true)
So, my questions are:
- Are the rules below correct?
How do I make a Swift call to find the people with a certain userId in the field name of an object type?
service cloud.firestore { match /databases/{database}/documents { match /users/{documentId} { allow read, write: if isOwner();
allow read: if getFriend(request.auth.uid) == true;function isOwner() { return request.auth.uid == resource.auth.uid; } function getFriend(userId) { return getUserData().friends[userId] } function getUserData() { return get(/databases/$(database)/documents/rooms/{documentId}).data } } }
}