title: Cloud Firestore rules on subcollection
body: <p>I'm working on an iOS app which has (whoah surprise!) chat functionality. The whole app is heavily using the Firebase Tools, for the database I’m using the new Cloud Firestore solution.</p>
  
  <p>Currently I'm in the process of tightening the security using the database rules, but I'm struggling a bit with my own data model :) This could mean that my data model is poorly chosen, but I'm really happy with it, except for implementing the rules part.</p>
  
  <p>The conversation part of the model looks like this. At the root of my database I have a <code>conversations</code> collection:</p>
  
  <pre><code>/conversations/$conversationId
          - owner // id of the user that created the conversation
          - ts // timestamp when the conversation was created
          - members: {
                  $user_id_1: true // usually the same as 'owner'
                  $user_id_2: true // the other person in this conversation
                  ...
            }
          - memberInfo: {
                  // some extra info about user typing, names, last message etc.
                  ...
            }
  </code></pre>
  
  <p>And then I have a subcollection on each conversation called <strong>messages</strong>. A message document is a very simple and just holding information about each sent message.</p>
  
  <pre><code>/conversations/$conversationId/messages/$messageId
          - body
          - sender
          - ts
  </code></pre>
  
  <p>And a screenshot of the model:
  <a href="https://i.stack.imgur.com/irMFg.png" rel="noreferrer"><img src="https://i.stack.imgur.com/irMFg.png" alt="the model"></a></p>
  
  <p>The rules on the <strong>conversation</strong> documents are fairly straightforward and easy to implement:</p>
  
  <pre><code>match /conversations/{conversationId} {
    allow read, write: if resource.data.members[(request.auth.uid)] == true;
  
    match /messages/{messageId} {
          allow read, write: if get(/databases/$(database)/documents/conversations/$(conversationId)).data.members[(request.auth.uid)] == true;
    }
  }
  </code></pre>
  
  <h3>Problem</h3>
  
  <p>My problem is with the messages subcollection in that conversation. The above works, but I don’t like using the <code>get()</code> call in there.
  Each <code>get()</code> call performs a read action, and therefore affects my bill at the end of the month, see <a href="https://firebase.google.com/docs/firestore/reference/security/?authuser=1" rel="noreferrer">documentation</a>.</p>
  
  <p><a href="https://i.stack.imgur.com/ysUnm.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ysUnm.png" alt="..."></a></p>
  
  <p>Which might become a problem if the app I’m building will become a succes, the document reads ofcourse are really minimal, but to do it every time a user opens a conversation seems a bit inefficient. I really like the subcollection solution in my model, but not sure how to efficiently implement the rules here.</p>
  
  <p>I'm open for any datamodel change, my goal is to evaluate the rules without these <code>get()</code> calls. Any idea is very welcome.</p>