Reputation: 73
Is there a native or efficient way to restrict the user to load a document from a collection only once every 24h?
//Daily Tasks
//User should have only read rights
//User should only be able to read one document every 24h
match /tasks/{documents} {
allow read: if isSignedIn() && request.query.elapsedHours > 24;
}
I was thinking that I might be able to do this using a timestamp in the user document. But this would consume unnecessary writing resources to make a write to the user document with every request for a task document. So before I do it this way, I wanted to find out if anyone had a better approach.
Any ideas? Thanks a lot!
Upvotes: 0
Views: 1120
Reputation: 494
There is no real "efficient" way to do so, neither a native at the moment of writing. And finding an actual solution to this "problem" won't be easy without further extensions.
There are however workarounds like with cloud functions for firebase that open new options for solving various limitations firestore has.
A native solution would be keeping track somewhere in the database when each user last accessed the document. This would, as you mentioned, create unnecessary reads and writes just for tracking.
I would prefer a caching mechanism on the client and allow the user to execute multiple reads. Don't forget that if the user clears the cache on the device, he has to query the document(s) again and won't get any data at all if you restrict him completely that way.
I think the best approach, due to the high amount of reads you get, is to cache on client side and set only a limit control (see Request.query limit
value). This would look somehow like below:
match /tasks/{documents} {
// Allow only signed in users to query multiple documents
// with a limit explicitly set to less than or equal to 20 documents per read
allow list: if isSignedIn() && request.query.limit <= 20;
// Allow single document read to signed in users
allow get: if isSignedIn();
}
Upvotes: 0
Reputation: 317372
There is no native solution, because security rules can't write back into the database to make a record of the query.
You could instead force access through a backend (such as Cloud Functions) that also records the time of access of the particular authenticated user, and compare against that every time. Note that it will incur an extra document read every call.
Upvotes: 1