Reputation: 2310
My basic question is how do you setup Firebase rules to only allow access certain leaf nodes from their parent?
Lets say I have data that looks like this:
root: {
posts: {
post1: {
user: "foo",
post: "this is a post",
restricted: false
},
post2: {
user: "bar",
post: "this is another post",
restricted: true
},
post3: {
user: "bar",
post: "this is my final post",
restricted: false
}
}
}
I want to $bind
to the posts node and get all the posts which that user is allowed to get. I might want the admin to access all of the posts but non-admins to only be able to access post1 and post3.
Note: I'm using angularFire's $bind to synchronize nodes.
I don't believe this is possible but I would like to be able to set up my rules kinda like this:
{
"rules": {
"posts": {
".read": "auth.admin || $post.hasChild('restricted').val() !== true",
"$post": {
}
}
}
}
How are other users accomplishing this? Thanks.
Upvotes: 2
Views: 1850
Reputation: 1008
I believe the canonical way to do that is to place a rule directly on the element to be read, not on the collection.
{
"rules": {
"posts": {
"$post": {
".read": "auth.admin || data.hasChild('restricted').val() !== true"
}
}
}
}
Upvotes: 0
Reputation: 7428
You can use the data.hasChild
expression to achieve this:
{
"rules": {
"posts": {
".read": "auth.admin || data.hasChild('restricted').val() !== true"
}
}
}
However, this is not the recommended approach and won't work in practice. Security rules are not a good fit for filtering data based on access - you'll see permission denied errors in the console because angularFire will try to read all the posts from /blog and it will fail.
Instead, each user should know which posts they have access to and only fetch those directly. You can use push()
(or $add
in angularFire) to generate random post IDs and set the security rules such that you can access the data if you know the post ID, for example.
Upvotes: 3