I am trying to make a project in firebase where I have a collection for say, users. The admin has to do multiple operations on these users and in short, need all these on-screen. I am currently having 1 document for each user in my "users" collection. Everything is working fine, but since the admin seems to be fetching all records many times a day, my Firestore reads are exceeding the free tier.
Now the logical solution to this seems to be that I put all the users inside a single document called users. I can use userIds as keys or store them in an array for convenient querying. But something tells me it is not such a good idea after all due to security concerns, as all my data is exposed in this case even to non-admin users.
What could be a middle ground solution to this issue?
CodePudding user response:
Now the logical solution to this seems to be that I put all the users inside a single document called users.
That's certainly a solution to go ahead with. But this doesn't mean you will have to give up storing the users in the collection. You should store all users in a collection as well as in a document/documents. This type of operation is called denormalization, and it's a common practice when it comes to NoSQL databases. For more info I recommend you read my answer from the following post:
That being said, you can keep your users from the collection in sync with the user objects from the document/documents.
since the admin seems to be fetching all records many times a day, my Firestore reads are exceeding the free tier.
Since you are talking about reading, then your admin should always read the data in the document/documents and not perform a query each time they only want to read some user data. This means that you'll have to pay a few document reads rather than all of them.
If you need to perform other operations rather than simpler reading, for example, filtering, then you should perform a query on the "users" collection. Also remember, if one admin updates something in the collection, you should also do it in the document/documents.
To perform an update in an array of custom objects, I recommend you read the following article:
I have always used "document/documents" because most likely, all your users might not fit into a single document. And this is because the documents in Firestore have limits. You are limited to 1 MiB total of data in a single document. So most likely you'll have to duplicate the user data in more than one document.
I have also written an article called:
That might help you understand how to reduce Firestore costs. Besides that, also remember that the free tier is used for testing purposes and not for an app that should be available in the real world. So you might also consider upgrading your plan to the Blaze Plan.
But something tells me it is not such a good idea after all due to security concerns
Regarding security rules, you can secure the user documents to be available for reading only to admin users.
CodePudding user response:
There are several problems with adding all the users in an array in a single document:
- A document has 1 MB max size limit so you may not be able to store all users in a single doc and might have to add more such documents eventually.
- You won't be able to query based on a property in user document e.g.
where("age", ">=", 10)
. You'll have to fetch all the users (that doc) and filter on client side. - If you need to write security rules that allow users to read/write their own documents only, that might not be possible.
You could still have a document for each user (which eliminates problem 3 above) and have another document containing all users in an array for admin usage. So whenever an admin queries users, it'll only cost 1 read (or more is you need to shard data across multiple documents)