Imports for Firestore Security Rules Are The Best

Dennis Kugelmann
Firebase Developers
3 min readMay 25, 2020

Wait? What? Since when does Firebase support imports for security rules? Well, they (still) do not support imports, but we can kind of fake the support.

Security rules are great! They are easy to write, got more powerful over time, and by adding them to Git, they allow you to create accurate test environments.

The only problem we discovered while using Firestore for almost 2.5 years now is that they can get messy over time. You’ll have a lot of rules for your various collections, a growing list of helper functions at the top of your file, and maybe even validation functions generated by the protobuf-rules-gen plugin.

The logical approach to this would be to split the security rules and functions into different files or maybe even folders as Firebase does not support it out of the box. We have to write a little helper script.

The Imports

Let’s define a syntax

First, we have to settle on a syntax for imports:

The “include” statement does not work like a typical import. The “include” doesn’t have to be at the top of the file. We might want to add the contents of a file somewhere in the middle of another.

So I decided to call it “include” and not “import”.

Use it in an example

So let’s create two files. One file we want to import and another root file where we use the import:

The root file for our security rules
The file to import into the root file

Some details to keep in mind

With the way the import works, it allows us to insert the functions.rules in the Firestore service definition and enable us to use the request object in the isAdmin() function.

I can do this as I include the file inside of “service cloud.firestore” and “match /database/{database}/documents”.

However, I would not recommend this approach as it restricts where a file can be included.

I would rewrite the function to something like this:

Now, you always have to provide the request on each function call, or it will throw an error. Also, everyone using the function immediately recognizes that the function expects to get a request object.

The Script

And now to the import part how to construct your final security rule.

I’ve written a Node script as this will most likely be familiar to most Firebase developers due to Firebase Functions.

The script reads the content of the file and finds all “include” statements and simply swaps them out for the content of the file specified in the quotation marks.

And the import of the included file then also get resolved recursively until no more import statements are found in a file.

This script does not detect any circular imports, so make sure to avoid them, or the script will get stuck in an infinite loop.

You’ll now have to run the script every time you deploy your rules. This can be very easily done using a small change of the firebase.json configuration:

Just add thispredeploy script to the Firestore and/or Storage configuration to execute the node script from above.

That’s it!

Pretty straightforward, but very helpful to keep your security rules organized.

BONUS TIP: This also works for Cloud Storage security rules.
You could also share some functions between Firestore and Cloud Storage, like if a user is an admin based on custom claims.

--

--

Dennis Kugelmann
Firebase Developers

Tech Lead Content at simpleclub.com | Making students understand anything in the shortest time