1

I'm working on an app using Firebase. I have the following data structure on Firebase:

{
   rules: {
      "version": {
         "threads": {
            "$thread": {
               "noticeList": {
                   ".read": true,
                   ".write": true
               },
               "messages": {
                   ".read": "root.child('version/threads/' + $thread + '/users/' + auth.uid).exists()",
                   ".write": "root.child('version/threads/' + $thread + '/users/' + auth.uid).exists()"
               },
               "$other": {
                    ".read": "auth != null",
                    ".write": "auth != null"
               }
            }
         }
     }
}

Each thread has subnode /users/ and I want to make a rule that only included users can read and write the messages in that thread.

There are one more condition that I have to access to noticeList when the new messages are added. However, these rules do not work. If there are other node rules in the '$thread', I couldn't get any respond when I used

firebase.child("version/threads/" + $thread + "/noticeList").once("value", function(snapshot) {});

or

firebase.child("version/threads").once("value", function(snapshot) {});

How can I fix it?

Thanks

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

1 Answers1

2

Your query starts at this:

firebase.child("version/threads/" + $thread + "/noticeList")

When you execute this query, Firebase checks if the user has rights to read the node. Which in this case the user doesn't, so the query fails.

This is a common mistake people make when it comes to Firebase security rules. The Firebase documentation explains it as "rules are not filters", which is exactly what you're trying to do.

Unfortunately for your scenario, the documentation also explains that "rules cascade". This essentially means that if you give users read access to noticeList, you cannot take te read access away at a lower level.

The easiest way to get this to work is probably to give each user their own index of notices they can access.

version
  threads
    $thread
      userNoticeList
        <userid1>
          <messageid1>: true
          <messageid2>: true
        <userid2>
          <messageid1>: true
          <messageid3>: true

This is a fairly typical denormalization of the data.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks for your reply. We decide to change some logics and structure in our app through your comments. – Hyuk Jun Kim Jul 07 '15 at 02:46
  • do I understand it right that I have to always have a parent node if I want to give only the owner user access to the data? – daniel Nov 10 '15 at 22:44