2
votes

I am new to using Firebase and feel myself completely lost with DB rules. I need to allow users to read items that have owner field equal to specific value.

This is the records structure I have:

{
  "books" : {
    "-LKwbZsfy55d24kwX4tf" : {
      "description" : "Adventures",
      "title" : "Captain Donsak",
      "owner" : "b7bS753Hvc0fmQ24Jnc"
    },
    "-LKwc1Xna07nequDtpF6" : {
      "description" : "History",
      "title" : "World War II",
      "owner" : "hLoOnnv4883Vhvm9Vt4"
    },
    "-LKwi4qcsqbgvZPdhCXp" : {
      "description" : "Adventures",
      "title" : "Sea Wolf",
      "owner" : "umV4hFm96vpdwBytx63"
    }
  }
}

I've tried several options of rules, including following (these were provided in firebase docs), but in any case it returns 0 items when I apply any of these rules.

{
  "rules": {     
    "books": {
        ".read": "data.child('owner').val() === 'umV4hFm96vpdwBytx63'",
        ".write": "auth != null"   
    }
  }
}


{
  "rules": {     
    "books": {
      "$uid":{
        ".read": "root.child('owner').val() == 'umV4hFm96vpdwBytx63'",
        ".write": "auth != null"   
      }        
    }
  }
}

If I just specify

".read": "auth != null"  

it returns all records, but this is not what I need.

I use a simple js command to read the data:

const itemsRef = firebase.database().ref('books'); 

Basically what I need is to filter data using security rules, but this is not possible as stated by RenaudTarnec below. So I'll have to use js to filter it:

const itemsRef = firebase.database().ref('books').orderByChild('owner').equalTo(owner); 

Please advise what could be wrong. Thank you.

3
your rules say check if the owner equals your hardcoded uid - Android Admirer
use auth.uid instead of 'umV4hFm96vpdwBytx63' - Android Admirer
Can you please edit that information into your question? Not everyone reads comments and to help us help you it is best to make your question as complete as possible :) - André Kool
@AndréKool, added this info to my question. Thank you. - Liu

3 Answers

3
votes

Actually "Firebase rules are not filters", see https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters

It means that, to fetch this data, you have to use a query that is "aligned" with your security rules.

Like the following in JavaScript, see https://firebase.google.com/docs/database/web/lists-of-data

var query = firebase.database().ref('books').orderByChild('owner').equalTo('umV4hFm96vpdwBytx63');
3
votes

According to @AndréKool suggestion, this is how I solved this question: In order to filter the response items, I used query based security rule:

{ 
  "rules": { 
      "books": { 
          ".read": "query.orderByChild == 'owner' && query.equalTo == auth.uid", 
          ".write": "auth != null" 
        } 
     } 
  }

And I use a js filtering accordingly:

const itemsRef = firebase.database().ref('books').orderByChild('owner').equalTo(owner);

Thanks everyone for your help! ;-)

0
votes

Try that:

{
  "rules": {     
    "books": {
      ".read": "data.child('owner').val() === auth.uid",
      ".write": "auth != null"   
    }
  }
}