2
votes

I am trying to setup security rules for my firestore instance, I have three basic requirements:

  1. User must be authenticated to read
  2. Owners of documents are the only ones who can write to them (use a field called owner on document to verify)
  3. Any admin user can also write to any document

The code below achieves all of this (excluded the check for ownership) but the get function to determine the users role only works when specified on the same row as the if condition. In the code below the update and delete works for the admin but not the create.

Can anyone please tell why the isAdmin() function does not evaluate to the same result?

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

    // Only 'owners' of data can make changes to data
    match /posts/{post} {    
      allow read: if isAuthenticated();
      allow create: if isAuthenticated() && isAdmin();
      allow update, delete: if isAuthenticated() && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 1;      
    }
  } 

  /// FUNCTIONS ///
  function isAuthenticated() {
     return request.auth.uid != null;
  }

  // function requestIsOwner() {
  //   return request.resource.data.owner == request.auth.uid;
  // }

  // function resourceIsOwner() {
  //   return resource.data.owner == request.auth.uid;
  // }

  function isAdmin() {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 1
  }
}
1
Are you saying it doesn't work in the console simulator, or when these rules are actually deployed? The console simulator is known to be incorrect in some cases.Doug Stevenson
For me it we as during deployment I seen this type of discrepancy with the console which doesn't help when you're trying to figure out what worksbeaver559

1 Answers

0
votes

You need to pass the database variable as argument in your function like this:

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

    // Only 'owners' of data can make changes to data
    match /posts/{post} {    
      allow read: if isAuthenticated();
      allow create: if isAuthenticated() && isAdmin(database);
      allow update, delete: if isAuthenticated() && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 1;      
    }
  } 

  /// FUNCTIONS ///
  function isAuthenticated() {
     return request.auth.uid != null;
  }

  // function requestIsOwner() {
  //   return request.resource.data.owner == request.auth.uid;
  // }

  // function resourceIsOwner() {
  //   return resource.data.owner == request.auth.uid;
  // }

  function isAdmin(database) {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 1
  }
}