title: Firebase: set security rules depending on user roles
body: <p>I would like to implement "write" security rules in Firebase depending on users roles.<br>
  My data structure is like this:</p>
  
  <pre><code>+ myapp
    + users
      + john
        + email: "john@mail.com"
        + roles
          + administrator: true
      + mary
        + email: "mary@mail.com"
        + roles
          + moderator: true
      + ...
    + documents
      + -JVmo6wZM35ZQr0K9tJu
        + ...
      + -JVr56hVTZxlAI5AgUaS
        + ...
      + ...
  </code></pre>
  
  <p>I want - for example - that only administrator users can write documents.<br>
  These are the rules I've come to:</p>
  
  <pre><code>{
    "rules": {
      ".read": true,
      "$documents": {
        ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
      }
    }
  }
  </code></pre>
  
  <p>But it doesn't work: not even administrator users can write documents...<br>
  Is my understanding of Firebase security rules totally flawed?</p>
  
  <p><strong><em>UPDATE</em></strong>:
  Just before Jenny's answer (believe it or not :-), I did implement the exact same solution he provides (of course based on Kato's comment).<br>
  Though, making some tests, I could not let the rules structure</p>
  
  <pre><code>{
    "rules": {
      "documents" {
        "$document" {
          ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
          ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
        }
      }
    }
  }
  </code></pre>
  
  <p>work... I always got a warning like this:</p>
  
  <pre><code>"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "
  </code></pre>
  
  <p>So I came up with this structure, instead:</p>
  
  <pre><code>{
    "rules": {
      "documents" {
        ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
        ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
      }
    }
  }
  </code></pre>
  
  <p>Which indeed works, for me: if I set a roles/customers/read node to true on a user he can read all documents, otherwise he can't (and the same for write).</p>
  
  <p>My doubts now are:</p>
  
  <ul>
  <li>why I could not let the first rule (as suggested by Kato) work?</li>
  <li>do you see any possible security hole in a rule like the one I did came up with?</li>
  <li>are rules using "$" variables necessary/useful even if you don't have to allow/deny the readability/writeability of each single
  document based on it's key, but you just want to allow/deny the
  readability/writeability of a node as a whole?</li>
  </ul>