0

I am following the documentation to setup rules. It's a simple chat app and I want to retrieve only the recent messages (i.e. messages that were created in the last X mins). I found the following document and tried exactly the same thing.

Structure

enter image description here

Rules

{
  "rules": {
    "messages": {
      "$message": {
        ".read": "data.child('timestamp').val() > 1" // try allowing everything
      }
    },
    ".write": true
  }
}

It looks like none of the messages are retrieved. As a workaround for this, I'm doing it on the client-side like this:

messagesRef.orderByChild('timestamp')
  .startAt(Date.now() - 600000)
  .on('child_added', (data) => {
    // do something
  })

Hopefully someone can help me out with the rules!

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Maximus S
  • 10,759
  • 19
  • 75
  • 154

1 Answers1

0

The documentation you refer to secures the node of each individual message. So /messages/-LDR_...ADvS is accessible if its not too old.

But your query is reading from /messages, where you haven't granted anyone permission.

This is an example of one of the most common pitfalls in Firebase security rules: rules are not filters. For more on this I recommend checking the section rules are not filters in the Firebase documentation, this first question explaining it, or some of the many questions mentioning "rules are not filters since then.

But things changed a bit earlier this year. While security rules can still not be used to filter data, they can be used to validate queries. For example, see this example from the documentation on query based rules:

"baskets": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'owner' &&
            query.equalTo == auth.uid" // restrict basket access to owner of basket
}

This allow reading from /baskets as your as you query by owner == uid. So now we grant the user access to /baskets, but only if they meet the condition our server-side security rules specify.

Unfortunately the last time I checked, the current timestamp was not available in query, making it impossible to write rules that only allow your workaround query.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807