MattCochrane
MattCochrane

Reputation: 3090

Firestore security rules allow user access to their data

I want to write a rule like this:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/{document=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

That is, I want to allow all read and write operations to all of a user's data if that user is the authenticated user.

Unfortunately that does not work. I get an error specifying that I don't have permission to access the data.

Upvotes: 2

Views: 4166

Answers (3)

Marc
Marc

Reputation: 411

Please note that this only works if you have made a 'users' table in your database and populated it with users that are known to your application (possibly copied from FireBase's users section Authentication/users in the webconsole).

AfaIcs you cannot refer to the Firestore authenticated users table this way. I found this lack of information very confusing since all examples and Firestore documentation make you believe that you can access the users created through the webconsole this way, invariably resulting in an 'access denied' messages when trying to read from a users table...

Upvotes: 1

Yulian
Yulian

Reputation: 6759

From the official documentation:

Another common pattern is to make sure users can only read and write their own data:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;
    }
  }
}

If your app uses Firebase Authentication, the request.auth variable contains the authentication information for the client requesting data.

Upvotes: 1

MattCochrane
MattCochrane

Reputation: 3090

This code solved the problem:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
      match /{document=**} {
        allow read, write: if request.auth.uid == userId;
      }
    }
  }
}

I think it's because you need to grant access to /users/{userId}, as well as /users/{userId}/{anyDoc=**}.

Upvotes: 7

Related Questions