Firebase firestore unique values in multiple fields - firebase

I'm creating an application for generating documents with unique id, my issue is that the id needs to be in a specific format ( 00000/A/B) so I can't use firestore document's id's.
The problem is also that I have that id's in different places,
#1 case
users/{userID}/id = //UNIQUE ID HERE
#2 case
users/{userID}/members <= members is an array of objects where every member need a unique id
I was thinking about the separate collection of id's where I can check which one is taken but maybe is there a better way to ensure id is unique across the whole app?

What you're considering is pretty much the only way to guarantee uniqueness of a value across the database.
In a few more structured steps, it'd be:
Use that value as the document ID in an secondary collection. This collection purely exists to ensure uniqueness of the IDs.
Let the user claim it, typically by writing their UID into the document.
Use security rules to ensure a user can only write a document if it doesn't exist yet, and (if needed) only deleted when they own it.
The topic of unique values has been covered quite a few times before, although usually in the form of unique user names, so I recommend checking out:
Cloud Firestore: Enforcing Unique User Names
How to generate and guarantee unique values in firestore collection?
How to enforce Uniqueness in a Property of a document field in Google Cloud Firestore
Firestore unique index or unique constraint?
I want to make unique usernames in firebase/firestore

Related

How to enforce Uniqueness in a Property of a document field in Google Cloud Firestore

I have the following data as shown in the image.
I want to make sure that the username field is unique. How can I enforce that? Bear in mind that my document id is already unique and I don't want to use my username as the document ID
There is no way to enforce unique values of fields in Firestore. The only uniqueness you can guarantee is the document IDs within a collection, so the solution is to create a new collection where the user names are used as document IDs.
This has been discussed a few times before, so I recommend checking out:
Firestore security rule to check if character username already exists
Check a document field for a specific value in Cloud Firestore
I want to make unique usernames in firebase/firestore, which shows some of the relevant security rules.
Cloud Firestore: Enforcing Unique User Names
Firestore unique index or unique constraint?, a more complete write-up with code and rules samples.
Cloud Firestore: Enforcing Unique User Names

How to turn off automatic indexes in firestore for subcollection

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.

Can I reuse existing fields as Sharded timestamps in Firestore?

I was looking for a solution to Firestore's limitation of Sequential indexed fields which means the following from this doc.
"Sequential indexed fields" means any collection of documents that
contains a monotonically increasing or decreasing indexed field. In
many cases, this means a timestamp field, but any monotonically
increasing or decreasing field value can trigger the write limit of
500 writes per second.
As per the solution, I can add a shard field in my collection which will contain random value and create a composite index with the timestamp. I am trying to achieve this with the existing fields I have in my Document.
My document has the following fields:
{
users: string[],
createdDate: Firebase Timestamp
....
}
I already have a composite index created: users Arrays createdDate Descending. Also, I have created Exemptions for the fields field from Automatic index settings. The users field will contain a list of firebase auto-generated IDs so definitely its random. Now I am not sure whether the field users will do the job of field shard form the example doc. In this way we can avoid adding a new field and still increase the write rate. Can someone please help me with this?
While I don't have specific experience that says what you're trying to do definitely will or will not work the way you expect, I would assume that it works, based on the fact that the documentation says (emphasis mine):
Add a shard field alongside the timestamp field. Use 1..n distinct values for the shard field. This raises the write limit for the collection to 500*n, but you must aggregate n queries.
If each users array contains different and essentially random user IDs, then the array field values would be considered "distinct" (as two arrays are only equal if their elements are all equal to each other), and therefore suitable for sharding.

How does String id = db.collection("myCollection").document().getId() gives document Id without hitting Firestore database?

I read somewhere that db.collection("mycollection").document().getId(); gives document Id in mycollection without hitting cloudstore database. But how it is possible to create unique Id without knowing document id of already existing doucments or hitting couldstore?
The auto-ID that is generated when you call document() is a fairly basic UUID (universally unique identifier). Such identifier are statistically guaranteed to be unique. In my words: there is so much random information in there, that the chances of two calls generating the same value are infinitesimally small.
So Firestore doesn't actually call the server to check whether the ID it generates is unique. It instead relies on the mathematical properties of picking a single value out of a sufficiently large and random set to be very certain it is unique.

Correlating Firestore indexes to slugs in a webapp

I'd like my web app router slugs to correspond to my Firestore documents data.
For example:
www.mysite.com/restaurants/burger-king
/restaurants <- Firestore Collection
/restaurants/mcdonalds <- Firestore Document
/restaurants/burger-king <- Firestore Document
This is easy enough, as I can assign the name as a slug-friendly UID in Firestore. The difficulty arises with CRUD functionality. I need to be able to rename my item titles, but Firestore does not permit you to rename indexes, which is the issue I'm facing.
One SO solution I saw was to delete the old record and creates a new one at the updated index. That's problematic for me, because sub-collections would be hard to transfer from the client side.
Are there more elegant solutions?
You don't have to identify a document by its ID. If you're able to ensure uniqueness of a document field value, you could instead query a collection for an ID value in a known field, then use the results of that query to satisfy your REST API. Then, you can change the value of that document field as often as you want, in order to satisfy required changes to the public API.

Resources