TUTORIAL: Firestore security rules - how to enable security so user have access to only their data

Hi,

I couldn’t find any topics giving the solution. So, here’s a simple tutorial on how I set up security rules in my app, so users have access to only their data.

Before going further on the topic, I strongly recommend the read of firestore security rules docs.

As a start: there are five categories for Firestore security rules:

get: get a single document
list: get (list) multiple documents from a collection
create: write a new document
update: update a document
delete: deletes a document

It’s important to say that those security rules are to protect, from anyone, modifying the database as you don’t intend. (Depending on the security rules, a person could easily get the API KEY from your app and do whatever they wish in the database).

My app: My app is a flashcard with spaced repetition algorithm to study English. The backend database in Firestore is comprised of four collections with different access rules:

  1. cards: any authenticated user may read single documents, but not list, create, update or delete any document.
  2. global_settings: same as cards
  3. tracker: any authenticated user may create new documents, but not list, get, update, or delete any document.
  4. users: it contains the user data. For each document in user collection, there are also two subcollections: study_progress and current_sesstion. User may create, get and update only their data, but not delete it.
    4.a: study_progress: The user may create, get, list, update, their data, but not delete it.
    4.b: current_session: The user may create, get, list and delete their data, but not update it.

Here’s how the security rules is set up:

  1. The wild card {allDocuments} means all documents inside the collection. Fore example match /global_settings/{allDocuments}, will matches all documents inside the collection global_settings.

  2. if request.auth != null used to allow only authenticated users.

match /users/{userId} {
    	allow get, create, update: if request.auth.uid == userId;

The wildcard {userId} is the document name for each user. In order this code to work, the document ID for each user, should always be the same as the one in the firebase authentication. if request.auth.uid == userId; will ensure each user has access to the document inside the usercollection which the ID match their user ID.

That’s it!

8 Likes

Hi @Alan_Alves , I;ve an use case where I only restrict write permission to authenticated users (I’m using Firebase auth). Trying this rule but its restricting even for read, if the user is not logged in. Can you please suggest where I’m possibly going wrong?

rules_version = ‘2’;
service cloud.firestore {
match /databases/{database}/documents {
allow read;
allow write: if (request.auth != null);
}
}

That’s the JSON inside firebase? are you using the custom? I mean like
{
test@test.com
pw: ****
if admin = true
}

I might be wrong, but I think that after 30 days if you haven’t written your own rules read/write default to false in firebase. The part where you initially decide to be public or test server. If you picked public it will be open but only for 30 days, if you choose the other option read/write default to false. Someone isn’t logged in they cant do anything because there is nothing they have authenticated too to give them permissions.