Search code examples
google-cloud-firestorefirebase-security

How write Firestore rule to match email field in document


I have a field labelled 'email' in my 'myCollection' documents and I'm trying to write a firestore rule to permit deletion when the email record of a logged-in user matches the email in the record. I've coded my rule as follows:

match /myCollection/{email} {
  allow delete : if request.auth != null && request.auth.token.email == email;
}

This fails to permit the deletion of matching records. Advice would be appreciated because although this question has been asked numerous times on StackOverflow, the answers I've seen are contradictory and none of them works for me.

I'm testing this in "playground" and if I set 'location' to myCollection/{documents = **}, the rule fails. See screenshots below:

Playground (top) Playground (bottom)

The deletion code in my program reads:

    const myCollectionCol = collection(db, 'myCollection');
    const myCollectionQuery = query(myCollectionCol, where("email", "==", email));
    const myCollectionSnapshot = await getDocs(myCollectionQuery);
    myCollectionSnapshot.forEach((doc) => {
        deleteDoc(doc.ref);
    });

Solution

  • You're firing a query that returns all documents that have a field email with a value equal to the email variable:

    query(myCollectionCol, where("email", "==", email))
    

    But your rules only allow deleting the document that has its *document ID equal to the user's email property in their auth token.

    So to delete the only document you're allowed to delete:

    import { getAuth } from "firebase/auth";
    
    const auth = getAuth();
    const user = auth.currentUser;
    const myEmailAddress = user.email;
    
    ...
    
    const myCollectionCol = collection(db, 'myCollection');
    
    deleteDoc(doc(myCollectionCol, myEmailAddress)); 
    

    If you want a user to be able to delete all documents where email has their email address, that'd be:

    match /myCollection/{doc} {
      allow delete : if request.auth != null && 
                        request.auth.token.email == resource.data.email;
                                                 // 👆 the email field in the doc
    }