2

I am trying to display a list of messages based on the recipient but for now, let's keep it simple. I am just trying to display a list of messages.

My rule looks like this

{
"rules": {
  "communications" : {
    "$communication":{
      ".read" : true,
      ".write": true
    }
  }
}

For some reason though, my application does not want to read it

fireRef = new Firebase(url);
fireRef.auth(MY_TOKEN);
commsRef = fireRef.child('communications')
$scope.communications = $firebase(commsRef)

It only works if I have a rule looking like

{
"rules": {
  "communications" : {
    ".read" : true,
    ".write": true
  }
}

But that will cause problem as I would like to add condition on the children node of my communication. Something like:

{
"rules": {
  "communications" : {
    ".read" : true, ### I would like to get rid of this line as well and have the child handling it
    ".write": true,

    "$communication":{
      ".read" : "data.child('to').val() == auth.uid"
    }
  }
}

I am assuming that is because I have a $firebase on the communications and it needs some read or write rules but how do I get the event when a new message is added otherwise

Thanks

Matthieu
  • 352
  • 5
  • 17

1 Answers1

3

With respect to security rules, Firebase operations are all-or-nothing.

That means that lists of data sent to the client will never be incomplete, or filtered views of the complete server data. As a result, attempting to load all of the data at /communications will fail when using your first set of security rules, even though you do have permission to read some of the data there as governed by the child rule at /communications/$communication.

To handle this use case, consider restructuring your data such that each communication is indexed by recipient, i.e. /communications/$recipient/$communication, which will simplify your security rules.

Additionally, you could even make that bucket read-only by the recipient (i.e. .read: auth.id == $recipient) while allowing anyone to send a message to that user (i.e. .write: auth != null && !data.exists()). That last rule ensures that the sending client is authenticated and writing to a location that does not yet exist, such as a new push id.

Rob DiMarco
  • 13,226
  • 1
  • 43
  • 55
  • I was just going through your guide to structure data. https://www.firebase.com/docs/web/guide/structuring-data.html and wonder if I was making a mistake. Apparently I did. Thanks That explains why the chat needs a room even for 121 I guess. – Matthieu Oct 23 '14 at 15:23
  • Would it make sense to have a communications/$sender/$recipient/$communication or it is too nested? – Matthieu Oct 23 '14 at 15:26
  • @Matthieu There's no real worry about being "too nested" with Firebase, as our nesting limit is pretty high, and performance will be unaffected. The key is to structure your data such that it matches your access pattern. – Rob DiMarco Oct 23 '14 at 16:09
  • See also: [Security rules cascade](https://www.firebase.com/docs/security/guide/securing-data.html#section-cascade) – Kato Oct 27 '14 at 18:11