0

Let's imagine a simple scenario: A simple mail system in firebase in a tree like this:

{
 "users":{
    "user-0001":{
       "mailbox":{
        "user-0002":{
           "DSdljkdkd333klll":{
              "message":"Hi ! I am user-0002 and I sent to user-0001 a message"
           },
           "JjkJHHH8888Gggg2":{
              "message":"Hi ! It's Me, user-0002 again !"
           }
        }
     },
     "secretStuff":"Something Private - nobody can write anything here",
     "myContacts":"This is my contact list. Obviously just me can access"
    },
    "user-0002":{
       "mailbox":{
         "user-0056":{
           "DSdljkdkd333klll":{
              "message":"Party tonight ! Don't forget !"
           }
        },
        "user-0282":{
           "3893NJJj33333eddf":{
              "message":"How are you ?"
           }
        }
     },
     "secretStuff":"Something Private - nobody can write anything here",
     "myContacts":"This is my contact list. Obviously just me can access"
  }
 }
}

Me as user-0002 , I can write on my own tree.

Ok, but I should be capable to write at user-*/mailbox/user-0002 because I can send a message to any user that I want. And of course: I can't have access to any other key.

So, how to archive this : A rule where I can write on my tree and in an adjacent tree like the example above ?

Marco Jr
  • 6,496
  • 11
  • 47
  • 86

2 Answers2

0

You should keep public data and private data in separate top-level lists. So:

mailboxes
  user-0001
    user-0002:{
      "DSdljkdkd333klll":{
       "message":"Hi ! I am user-0002 and I sent to user-0001 a message"
      },
      "JjkJHHH8888Gggg2":{
       "message":"Hi ! It's Me, user-0002 again !"
      }
    }
  user-0002
    user-0056:{
      "DSdljkdkd333klll":{
       "message":"Party tonight ! Don't forget !"
      }
    },
    user-0282:{
      "3893NJJj33333eddf":{
       "message":"How are you ?"
      }
    }
contacts
  user-0001: "This is my contact list. Obviously just me can access"
  user-0002: "This is my contact list. Obviously just me can access"
secrets
  user-0001: "Something Private - nobody can write anything here"
  user-0002: "Something Private - nobody can write anything here"

Now you can secure access based on the type of information, and load specific types of information.

If you need all information for a specific user, you will need to read from all three places. But given that you'll usually do this for a specific user, those reads are not a scalability concern. Even if you need all info for multiple users, it's usually quite fast since Firebase pipelines the requests over a single connection.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Still not good, Frank. In this fashion, user-0002 for example can overwrite things for user-0005 for example. And of course: user-0002 can read any mailbox. It's important to isolate paths. – Marco Jr Jun 04 '18 at 09:22
0

After researching more and testing I conclude that this should work...

{
 "rules":{
  "users":{
     "$uid":{
        ".write":"$uid === auth.uid",
        ".read":"$uid === auth.uid",
        "mailbox":{
           "$uid":{
              ".write":" $uid === auth.uid"
           }
        }
     }
  }
 }
}

This means:

If I'm user-0001, I can read/write in anything at /users/user-0001, however I just can write in elsewhere if the path is /users/*/mailbox/user-0001

Marco Jr
  • 6,496
  • 11
  • 47
  • 86