I have a collection named triggers I want to limit the number of documents per user on this collection, let's say 5.
I can create a counter with a Firebase function and set it as read-only, but I do not know how to limit it to the rules.
With Firestore Rules, is it possible to limit?
I can create a counter with a Firebase function and set it as read-only, but I do not know how to limit it to the rules.
You can read the document where you are storing the count as shown below (e.g. in users collection):
match /triggers/{triggerId} {
allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.count < 5;
}
As Cloud Functions run asynchronously, this rule might fail if the user attempts to add multiple documents at once (i.e. document is added before the count is updated). You can alternatively add documents through a Callable Cloud Function as well and perform all validations there.
Related
I have to check a document value != a string value in the Firebase Security rules.
So I have to first check if the document exists and then check the value.
allow read: !get(path).data || get(path).data.value !== 'xyz';
As I am calling the get() method twice, will it count 2 reads? If yes, how can I write the logic so that I fetch the document data once and reuse it?
As per the documentation, you are only charged once.
You are only charged one read per dependent document even if your rules refer to that document more than once.
I don't want to have automatic indexes created by firestore because I need to remove and add every five minutes 50-100 documents (each doc has +/-60 fields) to my subcollection. This causes of big volume for "Cloud Firestore Index Write Ops" (300k / day for only one user) and Cloud Storage. I don't need to sort, filtering that documents so I suppose I can turn off automatic indexes, right?
I know that I can add exemptions for fields, but I don't know how can I use it for documents in subcollections. What should I pass in Collection ID and Field path if the path for documents is like:
mainCollectionName/{id}/subcollectionName/{document=**}
and when should I select a collection checkbox and when collection group checkbox?
Unfortunately, it's not possible to disable indexes or create exemptions for documents to be indexed. As clarified in this similar post here, this cannot be achieved and there is even a limit of 200 exemptions of fields that can be done - you can check the limits here.
For your case, indeed, you would have to exempt the fields individually and besides that, to create the exemption, to set the collection you use its id and not the path. So, you would only need to set in the Collection ID field the subcollectionName and then the field to be exempted.
In addition to this, feel free to raise a Feature Request in Google's Issue Tracker, so they can check about implementing an exemption of documents in the future.
I have three types of collections in my database.
User
Post
Like
I make a 'like' document such that it has a _user and _post attribute that stores the user and post id respectively.
Currently I am writing a database rule such that a 'like' document is not created if there already exist a document which has the attribute value _user with the user trying to create the object and the _post which has the id the user is liking.
How do I write a rule for this situation ?
I don't think Firestore has any rules that can enforce this at the moment. But I do have some suggestions for alternative approaches:
1. Replicate the like user id to the Post with a cloud function:
You can set up a Firebase Cloud Function that triggers on Create operations of the Like collection. This Cloud Function writes the id of the user into an array on the post called like_users. Then you can have a rule that say:
allow create: if request.auth.uid not in get(/databases/$(database)/documents/Post/$( request.resource.data._post).data.like_users;
(Only problem with this solution, I don't think there is such a thing as "not in", this needs some research)
2. Check if there is a duplicate with a Cloud Function:
You can set up a Firebase Cloud Function that triggers on Create operations of the Like collection. In the function you query for Like documents with the same user and post id. If a document already exists, you delete the most recent one.
3. Restructure your database:
You could remove the Like collection, and instead have an array called "like_users" on the Post collection. This will need you to put a rule that checks if the user exists in the "like_users" array, so I think we might have the same problem as in alternative 1. You will also need to have rules saying that the user is not allowed to update the other fields of the document, which is possible.
Firebase real time database.
I am trying to limit number of items returned from a query only by changing the db rrules on firebase
Is this possible? I dont want to change the app side code
What is the rule if i have to fetch top 100 using the limittofirst.
Firebase's server-side security rules merely determine whether a certain operation is allowed. They don't filter data by themselves.
If you want to retrieve the first 100 items, put a limitToFirst(100) in your query.
If you only ever want the first 100 items to be retrieved (as in: want other read operations to be rejected), have a look at the documentation on securing queries, which contains this example:
You can also use query-based rules to limit how much data a client downloads through read operations.
For example, the following rule limits read access to only the first 1000 results of a query, as ordered by priority:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
I have following use case..
I don't want to allow user control document limit in cloud firestore, I want to have firebase rule restrict it.
For eg. I have a products collection, user can do pagination (max=10) per page. if its browser side, user can easily change and get all the products list. Is there any settings or rules to control this?
You can protect this using the query property of the request object (see docs). Basically you can write a rule with a condition on the limit:
allow read: if request.query.limit != 10
The above rule will prevent the query from going through if the limit is not set to 10.