You can test out this extension right away!
-
Go to your Cloud Firestore dashboard in the Firebase console.
-
If it doesn't exist already, create a collection called
${COLLECTION_PATH}
. -
Create a document with a field named
${FIELD_NAME}
, then make its value a string you want to ensure it's unique. -
In a few seconds, you'll see a new collection in Firestore called
${AUX_COLLECTION_PATH}
with a new document, that document will have as the key the value of the field${FIELD_NAME}
of the document you just created in${COLLECTION_PATH}
. -
This newly created collection and documents, used in combination with Security Rules, will prevent the client creating documents with duplicate values for the specified field.
-
You also have the option to hash the
${FIELD_NAME}
selecting 'Yes' when prompted to hash the field upon installation, due to constraints on document IDs. -
If you want to check uniqueness for existing documents, you can configure the parameter
${DO_BACKFILL}
selecting 'Yes' when prompted to, this will create the aux collection with the docs containing the unique value for existing documents.
Write a document with id exampleId with the string "bob1234" to the field ${FIELD_NAME}
in ${COLLECTION_PATH}
will result in the following document written in ${AUX_COLLECTION_PATH}
:
{
bob1234: {
id: exampleId,
${FIELD_NAME}: bob1234,
},
}
Now, if a client-side app wants to create / update a document with the string "bob1234" to the field ${FIELD_NAME}
in ${COLLECTION_PATH}
, the following Security Rules witll throw an error, thus preventing the client to execute the write:
function isFieldAvailable() {
return !exists(/databases/$(database)/documents/${AUX_COLLECTION_PATH}/$(request.resource.data.${FIELD_NAME}));
}
function fieldDidNotChange() {
return request.resource.data.${FIELD_NAME} == resource.data.${FIELD_NAME};
}
match /${COLLECTION_PATH}/{id} {
allow read: if ...;
allow create: if isFieldAvailable();
allow update: if fieldDidNotChange() || isFieldAvailable();
allow delete: if ...;
}
If you opted in to hash the ${FIELD_NAME} due to contraints on document IDs, then your Security Rules change slightly, like this:
function isFieldAvailable() {
let field = hashing.md5(request.resource.data.${FIELD_NAME}).toHexString().lower();
return !exists(/databases/$(database)/documents/${AUX_COLLECTION_PATH}/$(field));
}
As a best practice, you can monitor the activity of your installed extension, including checks on its health, usage, and logs.