1

Assume the following.

posts : {
      "$postid":{
               "meta":{
                      "state":true,
                      "text" :"I should be read",
               },
               "likes":{
                      "uid1":true,
                      "uid2":true,
               },
       },
       "$postid":{
               "meta":{
                      "state":false,
                      "text" :"I should be read",
               },
               "likes":{
                      "uid1":true,
                      "uid2":true,
                      "uid3":true,
               },
       }
}

I want to query the parent node('posts') as follows.

  • Leave out posts with state = false
  • Prioritise posts with most likes

Security Rules

  • Deny posts with state == false to be read.

Here's the Javascript Version Of how I'm querying data. ////$.fdr === firebase.database.ref();

$.fdr("posts").orderByChild("time").limitToLast(20).once('value',function(r) {
    var r = r.val();
    if(r !== null){                 
        ///use r;  
    }
},function(e){
        console.log(e);
}); 

Why this: I want the user to delete a post, and be able to revoke the delete later on. To delete I change the value of "post.meta.state" to "false". While "post.meta.state" is false, security rules shouldn't allow that post to be read.

Problem : If i set rules inside the post node rather than the parent node("posts"),

 "postid": { 
             ".read":"data.child('state').val() == true"
           }

then I can restrict ".read", but only if i'll query posts as follows :

firebase.database.ref("posts/postid");

Otherwise if I try to query from the parent node like:

firebase.database.ref("posts/"), 

so that I can filter out posts I don't want returned, then I'll have to elevate the rules from "posts" children to "posts"(parent), which will cause the rules in the children to be ignored, and there I can't seem to find a way to deny returning posts with "state" == false;

The above is based on my understanding so far, please do correct where I'm lost.

Relm
  • 7,923
  • 18
  • 66
  • 113
  • You've undoubtably already tried something. Please share what you've tried and the minimum code that shows where you got stuck. At the very least that will tell us what platform you are targeting. But more likely it will also give us a much better idea of how to help you. – Frank van Puffelen Jul 17 '16 at 04:36
  • @FrankvanPuffelen please see the new edit. – Relm Jul 17 '16 at 17:17

1 Answers1

4

Unfortunately, it is not possible to block reading/writing on any child node when a user as permission to read/write the parent node. You can read more about how security rules cascade in the Firebase Docs.

That said, there are a couple possible solutions for you to consider:

  1. Instead of marking a post as deleted, you can move it out to a separate parent node. Then you can adjust the security rules for deleted_posts to hide it.

    {
      "posts": {
        "$postid1": {
          "meta": {
            "state": true,
            "text": "I should be readable"
          },
          "likes": {
            "uid1": true,
            "uid2": true,
            "uid3": true
          }
        }
      }
      "deleted_posts": {
        "$postid2": {
          "meta": {
            "state": false,
            "text": "I should not be readable"
          },
          "likes": {
          }
        }
      }
    }
    
  2. Keep a separate list of postids that are visible, and set the "posts" node to not readable, but the children to readable if not hidden. You will have to do a second query to get the data for each post:

    {
      "posts": {
        "$postid1": {
          "meta": {
            "state": true,
            "text": "I should be readable"
          },
          "likes": {
            "uid1": true,
            "uid2": true,
            "uid3": true
          }
        },
        "$postid2": {
          "meta": {
            "state": false,
            "text": "I should not be readable"
          },
          "likes": {}
        },
        "$postid3": {
          "meta": {
            "state": true,
            "text": "I should be readable"
          },
          "likes": {}
        }
      },
      "visible_posts": {
        "$postid1": true,
        "$postid3": true
      }
    }
    
Kiana
  • 1,415
  • 11
  • 17