Reputation: 1960
I need to have a list of things like such
clients/{clientId}/points/{pointId}
and the fields at this document would be something like
point aaaa = { device: '1234', messages: 2, color: 'red'... },
point bbbb = { device: 'AAAA', messages: 2, color: 'red'... },
a user has in the token the clientId and an array of devices
{
uid: 'abc',
token: {
clientId: 'test1',
devices: ['1234']
}
}
and my security rules look like this.
service cloud.firestore {
match /databases/{database}/documents {
match /clients/{clientId} {
match /visible/{document=**} {
allow read: if request.auth.token.clientId == clientId
}
match /points/{$pointId} {
allow read, write: if request.auth.token.clientId == clientId && resource.data.device in request.auth.token.devices;
}
}
}
}
So if I get point aaa directly it will work but if i want to get all points such as
firestore.ref('path/to/points').where('color', '=', 'red')
I get access denied.
So how do i get all of the points which i'm allowed to see (which will be in the thousands).
Upvotes: 0
Views: 418
Reputation: 317392
The issue here is that security rules are not filters. According to the documentation:
When writing queries to retrieve documents, keep in mind that security rules are not filters — queries are all or nothing. To save you time and resources, Cloud Firestore evaluates a query against its potential result set instead of the actual field values for all of your documents. If a query could potentially return documents that the client does not have permission to read, the entire request fails.
So, if your entire query may fail to read some document in the result set, the entire query fails. It sounds like your query is not exclusively returning documents that the user may read with their custom claims.
Upvotes: 1