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 collection myCollection and the documents inside publicData.
  • allow read: if true; is the rule we want to apply. In our case, we want to allow read access to everyone. The if 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 to true.

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!


Related Posts

Find posts on similar topics:


Comments