title: Firestore - accessing transactional/nested data in security rules
body: <p>I'm hoping someone can help me on this one. I really love the new Firestore beta but the lack of simulator/debugger at the moment has left me struggling with a problem.</p>
  
  <p>I have a collection of scenarios which can be up-voted or down-voted. I want to restrict anyone malicious up-voting/down-voting something multiple times so I also have a sub-collection of votes for the scenario. These are just documents keyed by userId that contain a hash like</p>
  
  <pre><code>{
    up: true,
    down, false
  }
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/cJN3L.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cJN3L.png" alt="enter image description here"></a></p>
  
  <p>In order to write these multiple items (i.e. scenario document and vote sub-collection) in one request I use a transaction.</p>
  
  <p>The problem I'm having is that I want to validate that when "points" is updated by a user it <strong>must</strong> be accompanied by a vote document that sets up/down to true, depending on the points and whether a vote already exists for a user.</p>
  
  <p>In the security rules, how is it possible to read if the vote sub-collection data exits in the request when I'm validating at the scenario document level (or visa-versa)? It's my understanding that "request.resource.data" only allows you to see the data for the current document level being written to (I could be wrong here but there's no easy way to check and there's nothing in the documentation). Here's an example of my security rules so far:</p>
  
  <pre><code>service cloud.firestore {
    match /databases/{database}/documents {
      // Scenarios
      match /scenarios/{scenarioId} {
          allow read;
        // Only allow write if all of these are true
        allow write: if request.auth.uid == request.resource.data.userId &amp;&amp;
                                              // points    
                                      request.resource.data.points == 0;
        allow update: if request.auth.uid != null &amp;&amp;
                         (
                          request.resource.data.points &gt;= (resource.data.points - 2) ||
                          request.resource.data.points &lt;= (resource.data.points + 2)
                         )
                         // TODO: Only allow write to points IF accompanied by a "votes" document for that userId
        // Votes
        match /votes/{voterId} {
          allow write: if voterId == request.auth.uid;
        }
      }
    }
  }
  </code></pre>
  
  <p>Note that the current +/- 2 points validation is because if a user has already down-voted a scenario they can increment by two points by performing an up-vote (removal of the existing down-vote + the new up-vote). This validation will become more sophisticated once I know how to access the "vote" details :)</p>