William Pepple
William Pepple

Reputation: 75

Failure to delete from Firestore with React

I am trying to delete a specific document on firestore but I am not getting it right, I will like to know what I am doing wrong, kindly look at my code below:

import { IconButton } from '@material-ui/core'
import { ArrowBack, CheckCircle, Delete, Email, Error, ExitToApp, LabelImportant, MoreVert, 
MoveToInbox, Print, UnfoldMore, WatchLater } from '@material-ui/icons'
import React from 'react'
import { useSelector } from 'react-redux'
import { useHistory } from 'react-router-dom'
import { selectOpenMail } from './features/mailSlice'
import "./Mail.css"
import firebase from 'firebase'
import { db } from './firebase'


function Mail() {
    const history = useHistory();
    const selectedMail = useSelector(selectOpenMail)

In the function below, I created a onClick event which when triggered will delete the document on the firestore, I used Redux for this project, that's why you can see mail slice above.

    const deleteMail = () =>{
        db.collection('emails').where('id', '==', selectedMail.id).get()
        .then((querySnapshot) => {
            querySnapshot.forEach((doc)=>{
                doc.ref.delete()
                console.log(querySnapshot)
            })
        })
        history.push("/")
        
    }
    return (
        <div className="mail">
            <div className="mail_tools">
                <div className="mail_toolsLeft">
                <IconButton onClick={()=> history.push("/")}>
                    <ArrowBack/>
                </IconButton>
                <IconButton>
                    <MoveToInbox/>
                </IconButton>
                <IconButton>
                    <Error/>
                </IconButton>
                <IconButton>
                    <Delete onClick={deleteMail}/>
                </IconButton>
                <IconButton>
                    <Email/>
                </IconButton>
                <IconButton>
                   <WatchLater/> 
                </IconButton>
                <IconButton>
                    <CheckCircle/>
                </IconButton>
                <IconButton>
                    <LabelImportant/>
                </IconButton>
                <IconButton>
                    <MoreVert/>
                </IconButton>
                </div> 
                <div className="mail_toolsRight">
                <IconButton>
                    <UnfoldMore/>
                </IconButton>
                <IconButton>
                    <Print/>
                </IconButton>
                <IconButton>
                    <ExitToApp/>
                </IconButton>
                </div>
            </div>
            <div className="mailbody">
                <div className="mail_bodyHeader">
                    <h2>{selectedMail?.subject}</h2>
                    <LabelImportant  className="mail_important"/>
                    <p>{selectedMail?.title}</p>
                    <p className="mail_time">{selectedMail?.time}</p>  
                </div>
                <div className="mail_message">
                      <p>{selectedMail?.description} </p> 
                </div>
            </div>
        </div>
    )
}

export default Mail

I checked my Redux developer tools and selectedMail is an object as shown below.

selectedMail : {
id:"Mx0XWGQGUiiBw9eQlAbA",
title:"Ewww",
subject:"Nayam",
description:"sjsjsjsjs",
time: "Tue, 31 Aug 2021 
}

Upvotes: 1

Views: 117

Answers (1)

samthecodingman
samthecodingman

Reputation: 26171

There are a number of issues that could be happening here, they include, but are not limited to:

  • The documents in the collection /emails, don't have a field called id
  • You are searching the wrong collection
  • selectedMail.id doesn't correspond to a valid document at the time you click the button
  • You don't have the appropriate permissions to delete that message
  • A network error
  • A syntax error

The most likely cause is the first one, the data of the documents under /emails don't actually have a field called id on the server side and it is added by your client code like so:

const selectedMail = await db
  .collection("emails")
  .doc(selectedId)
  .get()
  .then((snapshot) => ({
    ...snapshot.data(),
    id: snapshot.id
  });

To delete such an email, you could use either:

const deleteMail = () =>{
    return db
        .collection("emails")
        .where(FieldPath.documentId(), "==", selectedMail.id)
        .get()
        .then((querySnapshot) => {
            querySnapshot.forEach((doc)=>{
                doc.ref.delete()
                    .then(() => history.push("/")) // only navigate if it works!
                    .catch((err) => alert("Failed to delete email! " + (err.code || err.message)));
                console.log(querySnapshot)
            })
        })
        .catch((err) => alert("Couldn't search for email to delete! " + (err.code || err.message)));
        
}

or simplify it to just

const deleteMail = () => {
    return db
        .collection("emails")
        .doc(selectedMail.id)
        .delete()
        .then(() => history.push("/")) // only navigate if it works!
        .catch((err) => alert("Failed to delete email! " + (err.code || err.message)));
}

Upvotes: 2

Related Questions