Search code examples
google-cloud-firestorefirebase-security

Allow access to customer data if user is part of privileged collection


The database structure is like so:

  • suppliers(collection)>user_email(document)
  • customers(collection)>user_email(document)>foo(field)

And the current firestore.rules is like so:

match /databases/{database}/documents {

    //Base rule - fully restrictive
    match /{document=**} {
      allow read, write: if false;
    }

    //Checks if user is registered in the suppliers section
    function isSupplierTeam(request) {
      return exists(/suppliers/$(request.auth.token.email));
    }

    // Supplier self-data access
    match /suppliers/{email} {
      allow read, write: if request.auth.token.email == email;
    }
    match /suppliers/{email}/{document=**} {
      allow read, write: if request.auth.token.email == email;
    }

    // Checking the Customer Sub-Section
    match /customers/{email} {
      allow read, write: if request.auth.token.email == email || isSupplierTeam(request);
    }
    match /customers/{email}/{document=**} {
      allow read, write: if request.auth.token.email == email || isSupplierTeam(request);
    }
}

And the query run in javascript, when logged in as a "supplier" is:

db.collection("customers").get()
.then((querySnapshot) => {
  querySnapshot.forEach((doc) => {

    console.log(doc.id);
    console.log(doc.data());

  });
})
.catch((error) => {
  console.log("Error getting documents: ", error);
});

It doesn't seem to work and instead triggers a missing/insufficient permission error. How should I tweak my firestore.rules to allow suppliers to access the customer data?


Solution

  • So this works:

    //Checks if user is registered in the suppliers section
    function isSupplierTeam(request) {
      return exists(/databases/$(database)/documents/suppliers/$(request.auth.token.email));
    }
    

    It seems like the full "URL" is needed to access the relevant firestore document.