0

JSON

"users" : {
"02PdiNpmW3MMyJt3qPuRyTpHLaw2" : {
  "Coordinates" : {
    "latitude" : -24.809620667034363,
    "longitude" : 28.321706241781342
  },
  "Education" : "6", ........./// here are 10 Childs further on same level as education
  "Music"

The current rules

{
"rules": {
   ".read": false,
   ".write": false,
,    "users": {
       "$uid": {
         "Education" :{
         ".read": "$uid == auth.uid",
         ".write": "$uid == auth.uid"
}

According to my understanding, if I make users read rule for authorized users, it will override the education rule. This below is where users read rule is needed

  let artist = Database.database().reference().child("users").queryOrdered(byChild: "music").queryStarting(atValue:dateToday.timeIntervalSince1970*1000)
artist.observe(DataEventType.value,  with: {  snapshot in

Update: I had a typo "users" at the rules

uuuuuu
  • 119
  • 1
  • 7
  • You have `users` in your JSON and code, but `people` in your rules. Also the `music` property that you're ordering on, is not in the JSON. Can you edit the question to make sure these all match, and the value that you query on is present in the JSON. – Frank van Puffelen Dec 07 '20 at 21:33

1 Answers1

0

In general indeed the rule is that if you grant somebody read (or write) access to a node, they have the same access to all data under that node. So you can't just say ".read": true on /people as that will them to read the entire node.

What you can do is specify what query is allowed in your security rules. So to allow every to read all nodes with the given music value, you could do:

"baskets": {
  ".read": "query.orderByChild == 'music' &&
            query.equalTo > 1354867200000"
}

A few things to keep in mind here:

  • I hard-coded it here, but you will have to calculate the value for the filter in your rules somehow based on the now variable.
  • You can only filter on a single value, so you can't filter on both music and uid. You may be able to merge the two values into a single property and order/filter on that. For more on this see: Query based on multiple where clauses in Firebase
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • That could work I guess, if I rewrite some code so that fewer Childs are under baskets. But instead of equalTo, how would it work for my example. I tried: `".read": "auth.uid != null && query.orderByChild == 'music' && query.startAt(1444)"` but got error: Type error: `Function call on target that is not a function` – uuuuuu Dec 08 '20 at 11:48
  • That'd be `query.startAt == 1444`. – Frank van Puffelen Dec 08 '20 at 15:22
  • It still fails though. I tested it and it succeeds when I use just `auth.uid != null` and `auth.uid != null` with `&& query.orderByChild == 'music'`, but if I add `&& query.startAt == 9999 "`, it fails. That is of course when music child if bigger than 9999. I checked that it is bigger, but permission fails – uuuuuu Dec 10 '20 at 12:22
  • If the query fails with that condition, you're not passing `startAt(9999)`. There's really not much else that could be going on. – Frank van Puffelen Dec 10 '20 at 15:19
  • thought it might be string vs number issue. `startAt(9999) `should succeed if the music child is bigger than `9999`, right? – uuuuuu Dec 11 '20 at 07:57
  • I can't say if it's related to how you store the value, as I don't see the value that you're querying on in the JSON in your question. But if you store it as a string, then a numerical comparison won't work. – Frank van Puffelen Dec 11 '20 at 16:04