Securing Firebase Firestore with basic security rules
Aron Schüler Published
Intro
With Firebase Firestore, it has become extremely easy to store your web project’s data. However, it’s also very easy to build something that is very unsecure! The default protection allows read and write for everyone and requires you to change that after a given time period. This is called Test Mode when initializing Firestore and probably what most users pick.
Now, my project’s are all kind of similar. You have public data and you have user-specific data. So, you want some basic firebase security rules that allow public access to one document and restricted access based on the user id to the other documents.
Let’s see how to introduce that to our Firebase Firestore!
Granting access for the public data
Most apps have some kind of shared data that should be accessible for everyone. For firebase, that service configuration would then look like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Give read access to demo data set for everyone
match /myCollection/publicData/{documents=**} {
allow read: if true;
}
}
}
Let’s go through this line by line:
rules_version = '2';
is the version of the rules. We use version 2 here.service cloud.firestore
is the service we want to configure. In our case, that’s the Firestore.match /databases/{database}/documents
is the path to the documents we want to configure. In our case, we want to configure the documents in the current database.match /myCollection/publicData/{documents=**}
is the path to the documents we want to configure. In our case, we want to configure the collectionmyCollection
and the documents insidepublicData
.allow read: if true;
is the rule we want to apply. In our case, we want to allow read access to everyone. Theif true
part is the condition that needs to be met for the rule to apply. In our case, we want to allow read access to everyone, so we set it totrue
.
However, this leads to a problem. With this rule, we would allow everyone to read all documents in the publicData
collection. We only want logged in users to access the public data though! So, we need to change the rule to this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Give read access to demo data set for logged in users
match /myCollection/publicData/{documents=**} {
allow read: if request.auth != null;
}
}
}
The only change is the if
condition. We now check if the request.auth
object is not null. If it’s not null, the request has a user attached and we allow read access. If it’s null, we don’t allow read access.
Granting access for the user-specific data
Now, we want to allow read and write access to the user-specific data. We also want to restrict access to the user that owns the data. So, we need to add the user id to the path and check if the user id matches the user id of the request.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Give read access to demo data set for logged in users
match /myCollection/publicData/{documents=**} {
allow read: if request.auth != null;
}
// Give read+write access only if requesting user matches document's user id.
match /myCollection/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
The new match
statement allows read and write access to the documents in the myCollection
collection if the user is logged in and the user id of the request matches the user id of the document. This is the case if the user is the owner of the document.
Conclusion
This is a very simple example of how to secure your Firebase Firestore. You can read more about the rules in the firebase documentation.
How do you secure your Firebase Firestore and Firebase applications in general? Let me know in the comments below!