0

Is there a way to add a firebase security rule that prevents certain items in a collection from being read based on a value within each child item? My example: JSON:

orders{
  orderA: {
    name: x,
    company:a
    isDeleted: true
  }
  orderB: {
    name: y,
    company:a
    isDeleted: false
  }
}

It would be great to restrict users to be only able to read all orders where isDeleted === false

My Rule as I currently have (NOT WORKING):

"rules": {
    "orders": {
      ".indexOn": "companyId",
      ".read": "auth !== null && data.child('isDeleted').val() === false",
      "$ord": {
        ".write": etc
      }
    },...

The above doesnt work because "data" doesnt represent the right object - I can only use data inside the "$res" area. If I remove "&& data.child('isDeleted').val() === false" it works but of course brings back both records.

My request is something like this, so the $res doesn't apply - as I'm getting ALL orders by companyId http://mysite.firebase.io/orders?auth="xyz"&orderBy="companyId"&equalTo="a"

Is it even possible for a "retrieve all" type REST call like this and to filter out certain values via the firebase security rules? Am I just as well to retrieve all and then filter them out once I get them back in the front end??

funzeye
  • 103
  • 6

1 Answers1

0

Firebase's server-side security rules don't filter data. I highly recommend checking out the documentation, and some previous questions on this topic, as it's a very common misconception.

Instead the rules merely ensure that any read (in this case) operation, adhere to your requirements. So for your ".read": "auth !== null && data.child('isDeleted').val() === false", rule that means that the server checks if the user is logged in (they are), and that the node they are reading has a child isDeleted that is false. And since /orders/isDeleted does not exist, the read gets rejected.

You can securely allow access to only undeleted data by combining a query that only selects undeleted nodes with security rules that validate this query. Based on the example in the documentation on query based rules that'd look something like:

"rules": {
  "orders": {
    ".indexOn": "companyId",
    ".read": "auth !== null && 
              query.orderByChild == 'isDeleted' &&
              query.equalTo == false"
  }
}

This will work to get only non-deleted nodes. But since you can only order/filter on one property, you can't then also filter on companyId. You could allow that by introducing a synthesized isDeleted_companyId property, as shown in my answer here: Query based on multiple where clauses in Firebase

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807