Jeremy Belolo
Jeremy Belolo

Reputation: 4539

Firebase - secure location to be targeted with query

Hello guys,

I started to work on securing my Firebase. I have a location containing a list of events :

events:
    $event1: {
        name: test
        ...
    }
    $event2: {
        name: test2
        ...
    }

In my app, I let the user add events using their name. For that, after the user validates his input (eventName), I'm looking if that name exists using

ref.child("events").orderByChild("name").equalTo(eventName)

And if so, I will add it to the list of user's events. My issue is with security. If I define security rules like so :

"events": {
  "$eventId": {
    ".read": "auth != null"
  }
}

Then it fails - it's completely expected since "events" location, which is targeted by the Firebase reference, has no "read" rule. The problem is, I don't want to open the "events" location for read by all connected users, since events are private and must be shared directly by their name.

So, since this name must be unique, I could use it as the event object key in place of the Firebase generated key (I currently use .push() when a new event is created to add it to the list, Firebase generates me the key), but I really like the way it is now. So I ask before changing : is there another way to reach what I'm aiming to do ?

Thanks a lot ahead.

Upvotes: 0

Views: 61

Answers (1)

jwngr
jwngr

Reputation: 4422

The reason things don't work as expected here is that security rules are not filters. Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every child path is accessible, reading at the parent location will fail completely.

So, you would only be able to read from the /events/ node if you can read every child of that node. So if you are not logged in or you are not logged in with the correct user, the read will fail.

To accomplish what you want, you should add an /events/ node to each user in your /users/ node which just list the eventId for each event they are a part of. Then you don't need you event query and can instead just easily get a users events by doing a read at /users/$uid/events/. Then you can look up the event details from the /events/$eventId/ node and avoid any reads at the top-level /events/ node which is disallowed by security rules.

Upvotes: 1

Related Questions