Reputation: 583
the goal I would to achieve is to show to an authenticated user a list of "Events" shared with other users, and in particular, only the events where the user itself is member of.
the initial structure I had in mind was:
events:{
"eventId1":{
"title":"some text",
"members":{
"myAuthUID":true,
"anotheUserUId":true
}
}
"eventId2":{
"title":"some text",
"members":{
"anotheUserUId":true
}
}
}
the rules I put in place is the following one. but it failed the porpouse:
{
"rules": {
".read":"auth.uid !== null",
".write": "auth.uid !== null",
"events":{
"$evtId":{
".read":"data.child('members').child(auth.uid).exists()",
".write": "data.child('admins').hasChild(auth.uid)",
}
}
}
}
calling /events all the events are showm
calling /events/eventId2 with myAuthUID it succeed.
the result must be, for sure, to show only the eventId1 to muAuthUser
could you please help me to structure better the data model and/or refund the rule?
meanwhile I'll look for a solution to this simple problem :)
thanks
Upvotes: 0
Views: 518
Reputation: 598887
First things first: that top-level ".read":"auth.uid !== null"
means that all authenticated users can read the entire database. Once you've granted a permisson on a certain level in the database, you can't take that permission away at a lower level. So your .read
rule on /events/$evtId
is useless at the moment.
The next step is that rules are not filters. Firebase checks your rules when you attach the listener, and the entire condition will be evaluated at that time (and only at that time). In practice this means that security rules cannot be used to filter data. This has been asked frequently before, so I recommend you check out some of those previous questions on the topic.
Recently Firebase added the ability to secure the queries that you allow on a certain node. So you could allow reads from /users
, but then only if they order/filter on a certain property. For more on this, see the documentation on query based rules. However, I'm not sure this will allow your use-case. There was a similar question moments ago, so I recommend monitoring that one too, in case someone answers there: How to filter by orderByChild containing a string in Firebase query-based rules
My usual solution for your use-case: your current data model allows you to efficiently read/query the members for an event. It does not allow you to efficiently read the events for a member. To allow the latter, add an additional data structure:
members
memberId1:
events
eventId1: true
eventId2: true
memberId2:
events
eventId1: true
eventId3: true
Now this is a lot easier to secure.
Upvotes: 1