title: Firebase private chat schema and rules
body: <p>I am trying to setup private chat abilities in an app that I am working on and I'm having a bit of trouble wrapping my head around denormalizing the data/setting up the rules properly.</p>
  
  <p>After doing some reading, I realize that rules are all or nothing so using rules to filter is not an option.</p>
  
  <p>I've sketched out my basic idea on paper, and have pasted it below. Basically there would be two main routes, users and chats.</p>
  
  <p>Users would just be a keyed list, which each key matching an authenticated user. Then inside each member of the list I would just have each chat that the said user is in listed as a key.</p>
  
  <p>For the chats route I'd have a list of all of the chats.</p>
  
  <p>Now for the rules. </p>
  
  <p>Users would only be able to read their data in the list where the key matched their uid. For the write i'm less confident. I'm thinking I have to let anyone with authentication write, otherwise the user starting the chat could not notify others of the new chat by playing the chat id in their chat list in the users route.</p>
  
  <p>For the chats rules both read and write would only be allowed if the user is authenticated and the chat key is located inside their data in the user route.</p>
  
  <p>Does the seem like I'm going in the right direction?</p>
  
  <pre><code>users:{
  
    user1:{
      chat1: true,
      chat2: true
      ...
    },
  
    user2:{
      chat1: true,
      chat3: true
      ....
    }
  }
  
  
  chats:{
    chat1:{
      lastUpdate: timestamp,
      messages:{
        0:{
          from: user1
          to: user2,
          message: some message
        }
        ...
      }
    }
  }
  
  rules:{
    .read: false,
    .write: false,
  
    users:{
      $user_id:{
        .read: auth != null &amp;&amp; $user_id == auth.uid,
        .write: auth != null //not sure here as other users need to write here if the start a new chat
      }
    },
  
    chats:{
      $chat_id: {
        .read: auth != null &amp;&amp; root.child('users').child($chat_id).contains(auth.id),
        .write: auth != null &amp;&amp; root.child('users').child($chat_id).contains(auth.id)
      }
    }
  }
  </code></pre>