Can the below security rule ensure uniqueness of firstName, lastName, username, and email before creating a document in profiles collection?
match /profiles/{document=**} {
allow create: if request.auth.uid != null
&& (request.resource.data.firstName is string && resource.data.firstName != request.resource.data.firstName)
&& (request.resource.data.lastName is string && resource.data.firstName != request.resource.data.firstName)
&& (request.resource.data.username is string && resource.data.username != request.resource.data.username)
&& (request.resource.data.email is string && resource.data.email != request.resource.data.email)
}
For example, below is the data in Firestore collection profiles
{
"document1":{
"firstName":"Jek",
"lastName":"Choo",
"email":"jeksomething@gmail.com",
"username":"jek"
},
"document2":{
"firstName":"Cara",
"lastName":"Choo",
"email":"babycara@gmail.com",
"username":"cara"
}
}
I want to create the below new document, and this create access should be denied
{
"document3":{
"firstName":"Jek",
"lastName":"Choo",
"email":"jeksomething@gmail.com",
"username":"jek"
}
}
And I want to create the below new document, this should be allowed.
{
"document4":{
"firstName":"example",
"lastName":"com",
"email":"test@example.com",
"username":"example"
}
}
In conclusion, can the above firestore security rule help to ensure field value uniqueness before a document is allowed to be created?
It's important to understand what
resource
does with respect to rules that create new documents, which is the only rule you're showing here.resource
refers to "the (existing) document being written". This is in contrast withrequest.resource
which describes the document that doesn't yet exist, that is about to exist, if the write succeeds.To put it another way, in this section:
In the case of a create, there is no existing document being written. Therefore, you can assume that any matches against
resource
to fail. Therefore, this will not ensure uniqueness.In fact, you can not ensure uniqueness of any given document field for a create, since it's not possible in security rules to query all documents in the collection for existence for that field.
The only form of uniqueness observed by Firestore is that of the id of a document within a collection. All fields of that document can not be constrained to be unique by security rules, and there are no indexes in Firestore that ensure uniqueness.
If you need a field to be unique, you should check after the document creation by using Cloud Function trigger, then delete the document if it doesn't satisfy the requirements.