Firebase Firestore Unique Constraints

James Qualls
2 min readDec 4, 2017

--

I’m honestly a Google fan boy when it comes to cloud services. I’ve been using Firebase for a lot of my most recent projects. While searching for a solution to the problem of unique index’s in Firebase Firestore I came across this stack overflow post and decided to propose a solution until Google makes this feature available.

As of today there is no way to enforce a unique constraint on a Firebase Firestore document key according to asciimikea firebase security developer on twitter.

Since Firestore is backed by Google Cloud Datastore it inherits this issue. It’s been a long standing request since 2008.

However, you can simulate a uniqueness constraint by using Firebase Functions and some strict security rules.

Requirements

  • Ensure case insensitivity on usernames
  • Ensure a user can only have one username at any time
  • Allow a user to change their username while maintaining the above constraints
  • Secure the method for assigning a username with firebase id tokens
  • The operation should be atomic and performed in a transaction to avoid state issues

A firebase function that enforces uniqueness

Security rules

Notes

  • the code above bypasses these security rules since we’re securely performing those actions on a server
  • the client is implicitly disallowed from reading the usernames collection because there are no rules that allow it to do so
  • the client is explicitly disallowed from modifying their user record’s username field
  • we allow a user to modify any other property on their record except their username (managed by the Firebase Function)

Communicating with this firebase function

Once you’ve created and deployed your firebase function you will receive a URL in the dashboard. It should look like this.

https://{region}-{projectId}.cloudfunctions.net/{functionName}

This will serve the function we wrote above secured by firebase id tokens. You can acquire a token in the client by calling this method.

MAKE SURE YOU USE HTTPS or tokens will be sent in plain text

--

--