GMan
GMan

Reputation: 464

firebase firestore rules authenticated access to all collections except one

I have the following firestore structure, basically 3 collections

publicdata protecteddata1 protecteddata2

I want to have protecteddata1 and protecteddata 2, and really the entire firestore database as authenticated users only. But i want the public to have readonly access to 'publicdata' collection..

The following is my attempt but it doesn't work

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read;
      allow write: if (request.auth.uid != null);
    }
    match /publicdata {
       allow read;
    }
  }
}

Upvotes: 11

Views: 20958

Answers (3)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

As others have explained, if you have multiple matches for the same document they are OR'ed together, so you can't implement an exception with that.

What you can do though is capture the collection name in a variable, and then implement the exception in a single match:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{collection}/{document=**} {
      allow read: if collection != 'publicdata';
      allow write: if (request.auth.uid != null);
    }
  }
}

So here we allow reads from all collections except publicdata.

Upvotes: 9

arielhasidim
arielhasidim

Reputation: 824

Because here is says:

Overlapping match statements

It's possible for a document to match more than one match statement. In the case where multiple allow expressions match a request, the access is allowed if any of the conditions is true: ...

You can use this:

rules_version = '2';
service cloud.firestore {

  // Check if the request is authenticated
  function isAuthenticated() {
    return request.auth != null;
  }

  match /databases/{database}/documents {
    match /{document=**} {
        allow read, write: if isAuthenticated();
    }
    match /publicdata/{document=**} {
        allow read: if true;
    }
  }
}

Upvotes: 1

You can use the following functions I created to do this

function isUserAuthenticated() {
    return request.auth.uid != null; 
}

You can then use it like this:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if isUserAuthenticated();
    }
    
    match /publicdata/{itemId} {
      allow read : if true;
      allow create : if isUserAuthenticated();
      allow update: if isUserAuthenticated();
      allow delete: if isUserAuthenticated();
    }

    /* Functions */
    function isUserAuthenticated() {
      return request.auth.uid != null; 
    }
  }
}   

Upvotes: 13

Related Questions