Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
    }
  }
}
like image 606
GMan Avatar asked Apr 01 '20 14:04

GMan


People also ask

How do I fix insecure rules in Firebase?

If you receive an alert that your Cloud Firestore database isn't properly secured, you can resolve the vulnerabilities by modifying and testing your Cloud Firestore Security Rules. To view your existing Security Rules, go to the Rules tab in the Firebase console.

How do I set firestore database rules?

Use the Firebase console To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.

Does firebase Admin bypass rules?

The Firebase Admin SDKs access your database using a service account. Service accounts ignore the Cloud Firestore Security Rules, similar to how you can edit documents in the Firebase Console directly yourself.

Can I use firestore without authentication?

To be honest, without Firebase Authentication, it's not possible to accept writes to a database without Authentication and also avoid abuse, since anyone could write anything from anywhere on the internet.


2 Answers

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; 
    }
  }
}   
like image 35
Aryeetey Solomon Aryeetey Avatar answered Sep 25 '22 14:09

Aryeetey Solomon Aryeetey


The recursive wildcard here is allowing access to all collections:

    match /{document=**} {
      allow read;
      allow write: if (request.auth.uid != null);
    }

Once any rule allows access to a collection, that access cannot be revoked by any other rule.

What you will have to do is call out each individual collection in its own rule. Yes, that's kind of a pain, but it's your only option. It also makes it very clear to the reader of your rules what you intend to allow for each collection.

Also worth noting that this rule doesn't actually do anything at all, because it doesn't match any documents:

    match /publicdata {
       allow read;
    }

If you want to match documents in the publicdata collection, it needs a wildcard that matches document within that collection:

    match /publicdata/{id} {
       allow read;
    }

Remember that rules match documents for access, not collections.

like image 190
Doug Stevenson Avatar answered Sep 25 '22 14:09

Doug Stevenson