
Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
Understanding and Implementing Firestore Security Rules
Understanding and Implementing Firestore Security Rules
So far, we have just been interacting with Firestore using the test security rules. This basically lets us do whatever we want. Notice that we have been adding messages to our database without having to login or authenticate in any way. If we launch this application as is, it means absolutely anybody can read/write the data in our database.
It’s not enough to just make restrictions inside of our application either. Let’s say we didn’t have an interface in the application for adding a message
- it would still be possible for people to connect to our database and read/write as they please. If the security rules allow it, it can be done. We need to make sure our security rules describe exactly what can and can not be done and by whom.
These rules can be found in the Rules tab which is next to the Data tab
inside of your Firestore database (accessed through your project in the
Firebase console). But, we will generally
be using the firestore.rules
file inside of our project to manage our rules
and deploy them with:
firebase deploy
The set of rules which we have currently (since we are in test mode) looks like this:
rules_version = '2';
service cloud.firestore { match /databases/{database}/documents {
// This rule allows anyone with your Firestore database reference to view, edit, // and delete all data in your Firestore database. It is useful for getting // started, but it is configured to expire after 30 days because it // leaves your app open to attackers. At that time, all client // requests to your Firestore database will be denied. // // Make sure to write security rules for your app before that time, or else // all client requests to your Firestore database will be denied until you Update // your rules match /{document=**} { allow read, write: if request.time < timestamp.date(2023, 11, 25); } }}
This setup means that all reads and writes will be allowed to the
database, no matter who is making them. If you wanted to change these rules, you
would need to make modifications to them here and publish the new rules
(again, either through the Firebase console or locally and by running firebase deploy
).
In this lesson, we are going to go on a bit of a journey from creating basic security rules to the final security rules that our application will require in order to be secured to the level that we need. Along the way, this will allow us to explain various aspects of how Firestore Security Rules work.
We won’t be covering every aspect of Firestore Security Rules, there is just too much to learn, but this should give you a solid grounding for how creating security rules works in general. The exact kinds of rules you need to write will depend on the specifics of the application you are creating.
Despite my warning, please do attempt to learn and have fun with security in the right environment. Even if it may take a while to learn enough to start handling all security concerns yourself, knowing a little bit can provide you with a lot of insight.
Match & Allow
Creating Firestore security rules mostly comes down to these two concepts:
match
and allow
. We will use match
to target a specific collection or
document, and we will use allow
to define an expression to determine how
that specific collection/document may be accessed.
When writing our match
statements, there is a bit of boilerplate code that
mostly won’t change. For example, the default rules for a “locked” database (the
opposite of our “test mode” database) look like this:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } }}
This might look a bit intimidating, but we can mostly forget about all of this:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents {
}}
This code just means that we are targeting the firestore
service, and the
first match
statement just means we are targeting the default database in our
project — we won’t need to change this. All of the important stuff will be
inside of this initial match
, e.g:
match /{document=**} { allow read, write: if false; }
This particular match
uses the {document=**}
recursive wildcard to target
every document in the database, and in this case, it is blocking all reads and
writes. You won’t typically just use a blanket match
like this, but rather
target specific documents or collections with your match
statement, e.g:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents {
match /messages/{message} { allow read; allow write: if false; }
}}
In this case, we are attempting to match
the messages
collection. We use the
{message}
wildcard to match against any message in the collection, and then
this will also make a message
variable available to the allow
expression we
write (such that we could check the specifics of a document in our rule). You
don’t have to use a wildcard, you could also just match a single specific
document, but you can’t just match an entire collection by doing this:
/messages/
. If you want your security rules to apply to an entire collection,
you must use a wildcard: /messages/{message}
.
Although we are only matching one collection here, and this is all we will need for the application we are building, you can also match other collections or documents (or even sub-collections) and create different rules for those. For example, we might want to do something like this:
rules_version = '2';service cloud.firestore { match /databases/{database}/documents {
match /messages/{message} { allow read; allow write: if false; }
match /posts/{post} { allow read; allow write: if false;
match /comments/{comment} { allow read; allow create: if true; allow update, delete: if false; }
}
}}
Thanks for checking out the preview of this lesson!
You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).