title: Firestore rules when data doesn't exist
body: <p>I'm trying to create a rule that only lets a user create/edit a document in which <code>request.auth.uid</code> matches the name of the document they're trying to create. From <a href="https://cloud.google.com/firestore/docs/security/secure-data" rel="nofollow noreferrer">https://cloud.google.com/firestore/docs/security/secure-data</a>:</p>
  
  <blockquote>
    <p>Using variables from wildcards</p>
    
    <p>When you match a rule using a database path with a wildcard, a 
    variable is created with a name matching the string you included 
    inside the curly brackets. You can then reference these variables in 
    your security rules.</p>
    
    <p>One common use of these types of wildcards is to store documents by 
    userID, and then only allow users to access documents for which their 
    userID matches the ID of the document.</p>
  
  <pre><code>service cloud.firestore {
    match /databases/{database}/documents {
      match /users/{userIDFromWildcard}/ {
        // Users can only edit documents in the database if the documentID is
        // equal to their userID
        allow read, write: if request.auth.uid == userIDFromWildcard;
      }
    }
  }
  </code></pre>
  </blockquote>
  
  <p>I tried using this code in my rules, but it errors. When removing the last <code>/</code>, i.e. <code>match /users/{userIDFromWildcard}</code> instead of <code>match /users/{userIDFromWildcard}/</code>, it publishes, but permissions aren't granted if the document doesn't exist.</p>
  
  <p>Edit: I also tried something like this, but I don't know how to do it correctly because of the lack of documentation:</p>
  
  <pre><code>allow read, write: if request.auth.uid == request.resource.__name__;
  </code></pre>
  
  <p>This is the code I'm running that gets <code>insufficient permissions</code>:</p>
  
  <pre><code>this.items = afs.doc("/users/" + this.uid); // afs is AngularFirestore, this.uid is the uid of the authenticated user
  </code></pre>
  
  <p>...</p>
  
  <pre><code>// the user is authenticated at this point
  this.items.snapshotChanges().subscribe(snapshot =&gt; {
  if (!snapshot.payload.exists) { // if user isn't in db
      function recursive() {
          // ...
          this.updateDB(); // called once because of conditional
      }
      recursive();
      } else {
          // ...
      }
  }
  </code></pre>
  
  <p><code>updateDB</code>:</p>
  
  <pre><code>public updateDatabase(): void {
      const changes: Item = { name: this.name, username: this.username, 
      photoURL: this.photoURL };
      this.items.set(changes).then((item) =&gt; { // causes error
          console.log("Saving successful");
      }, (err) =&gt; {
          console.log(err);
      }).catch((err) =&gt; {
          console.log(err);
      });
  }
  </code></pre>