Relm
Relm

Reputation: 8241

Firebase : How to read every child node in parent except children with particular data

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.

Security Rules

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.

Upvotes: 1

Views: 1042

Answers (1)

Kiana
Kiana

Reputation: 1506

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
      }
    }
    

Upvotes: 4

Related Questions