I am using Cloud Firestore and I can't seem to get the "IN" operator to work with the security rules. I have tried using array and map but neither work. Of course when I set it to allow read, write;
it works fine. What am I doing wrong?
Rules:
service cloud.firestore {
match /databases/{database}/documents {
match /rooms/{roomId=**} {
allow read, write: if request.auth.uid in resource.data.users;
allow read, write: if request.auth.uid in resource.data.users2;
allow create: if request.auth != null;
}
match /user-rooms/{userId} {
allow read, write: if userId == request.auth.uid;
}
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
allow get, create: if request.auth != null;
}
}
}
Client:
db.collection("rooms")
.document(self.room.getRoomId())
.collection("messages")
.addSnapshotListener { .....
//Room is: d6l946swspNSouANzVdZ
//Username is: eX8gkxJNDREv
data
will return it's direct children not it's sub-children(users and users2) so you should use get
and exists
instead of in
match /rooms/{roomId=**} {
allow read, write: if request.auth.uid in get(/databases/$(database)/documents/rooms/$(roomId)/users/$(request.auth.uid)).data;
allow read, write: if exists(/databases/$(database)/documents/rooms/$(roomId)/users2/$(request.auth.uid));
allow create: if request.auth != null;
}
checkout the doc
You're trying to access a variable named "users" inside resource.data
which doesn't exist. The resource variable contains data from the object that is currently being written to the database.
What you're probably trying to do is check if this users exist in the fields users
and users2
, which can be achieved with the rules:
match /rooms/{roomId=**}{
allow read, write: if (exists(/databases/$(database)/documents/rooms/$(roomId)/users2/$(request.auth.uid)) ||
request.auth.uid in get(/databases/$(database)/documents/rooms/$(roomId)).data.users);
allow create: if request.auth!=null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With