edn
edn

Reputation: 2183

How to set Firebase security rule for read operation when user reads his/her own profile data

I am developing a Flutter app and using Firebase as backend. In my app, each user needs o sign up to be able to use the app and the user's profile data is saved in a user_profile collection.

Each user's profile data is stored in a separate document in the collection. The Document ID for each document is equal to the User ID, created by the Firebase Authentication when the user signs up for the first time. And I also save the User ID in a field (named uid) in each document as well for the corresponding user.

For the security part, I want that each user may only read his/her own profile data. I set the following rule:

// Rules for User Profile data
match /user_profile/{any} {
  allow read: if (request.auth != null) && 
                 (resource.data.uid == request.auth.uid) && 
                 exists(/databases/$(database)/documents/users/$(request.auth.uid));

Is it correct if I set my rules as given in the above example? (1) The user needs to be authenticated (2) The uid in the incoming request needs to be equal to the uid field in the corresponding document that the user wants to read. (3) The document with the uid available in the request must exist in the corresponding document

I cannot make it clear to me if I am making the whole thing unnecessarily complicated. For instance, does the rule (1) do the same thing as rule (2)? While I have rules (1) and (2), does it add anything to have rule (3) as well?

Upvotes: 0

Views: 589

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83093

Based on the following elements in your question:

  1. The user's profile data is saved in a user_profile collection
  2. The document ID for each (user's profile) document is equal to the User ID
  3. You want that each user may only read his/her own profile data

the following read security rule should do the trick:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'user_profile' collection
    match /user_profile/{userId} {
      allow read: if request.auth != null && request.auth.uid == userId;
      // ...
    }
  }
}

In other words, since the document ID for each (user's profile) document is equal to the userId you don't need to use the field containing the userId in the security rule: The wildcard expression {userId} makes the userId variable available in rules, see the doc.

Upvotes: 2

Related Questions