Josh Simon
Josh Simon

Reputation: 259

Firebase, React CRUD: Deleting a document by document ID

My component UniqueVenueListing displays a list of live music performances(gigs).
A complete list of gigs is brought in via an axios request in the GigRegister component and passed as props to UniqueVenueListing, where they are mapped over and rendered to the browser. I want to add delete functionality, so that logged in users can delete specific gigs.
Here's what I've done so far: In UniqueVenueListing, I wanted a real time subscription to database changes, so I included the following request:

const ref = firebase.firestore().collection('gig-listing')

const getGigs = () => {
    ref.onSnapshot(querySnapshot => {
        const items = []
        querySnapshot.forEach(doc => {
            items.push(doc.data())
        })
        setGigs(items)
    })
}

I then wrote a function to perform the deletion -

const deleteGig = () => {
    ref
    .doc(//some variable representing the specific doc id of a gig)
    .delete()
    .catch(err => {
        console.error(err)
    })
}

and finally I've got the button pointing to this delete function:

const button = <StyledButton onClick = {()=> {deleteGig(//some passed in gig)}}>Delete Gig</StyledButton>

So I've got all the 'bits', I just don't know how to tie them all together to produce a deletion. I want to be able to delete gigs based on gig ID, which I know can be retrieved from the getGigs function - console.log(doc.id) yields the IDs). Here's the entire component:

import React, {useState, useEffect} from 'react'
import Giglisting from './Giglisting'
import Button from "@material-ui/core/Button";
import { withStyles } from '@material-ui/core/styles';
import firebase from 'firebase'

const StyledButton = withStyles({
    root: {
      background: '#54ADA6',
      borderRadius: 3,
      border: 0,
      color: 'black',
      height: 30,
      padding: '0 30px',
      marginRight: '1px'
      
    },
    label: {
      textTransform: 'capitalize',
    },
  })(Button);


const UniqueVenueListing = (props) => {
const gigList = props.gigList
const [gigs, setGigs] =useState([])


const ref = firebase.firestore().collection('gig-listing')

const getGigs = () => {
    ref.onSnapshot(querySnapshot => {
        const items = []
        querySnapshot.forEach(doc => {
            items.push(doc.data())
        })
        setGigs(items)
    })
}

useEffect(() => {
    getGigs()
},[])

const deleteGig = () => {
    ref
    .doc(gigs.id)
    .delete()
    .catch(err => {
        console.error(err)
    })
}

const button = <StyledButton>Delete Gig</StyledButton>

    return(
        <div>
          {
              gigList.map(gigs => {
                 return <Giglisting
                 gigtitle = {gigs.name}
                  genre = {gigs.genre}
                  time = {gigs.time}
                  buytickets = {gigs.tickets}
                  button = {button}
                  />
              })
            }
        </div>
    )
}

export default UniqueVenueListing

Here's the part of the GigRegister component that filters and sends data to UniqueVenueListing:

      authListener() {
        auth().onAuthStateChanged((user) => {
          if (user) {
            this.setState(
              {
                userDetails: user
              },
              () =>
                axios
                  .get(
                    "https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings"
                  )
                  .then((res) => {
                    let filteredGigs = res.data.filter((gig) => {
                      return gig.user === this.state.userDetails.uid;
                    });
                    this.setState({
                      filterGigs: filteredGigs
                    });
                  })
            );
          } else {
            this.setState({
              userDetails: null,
            });
            console.log("no user signed in");
          }
        });
      }

      componentDidMount() {
        this.authListener();
      }

Upvotes: 0

Views: 330

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

The problem starts in your `` function, where you are extracting the data of each document, but are ignoring the document IDs that you need later. You'll want to change that function to get both the data and the ID for each document:

const getGigs = () => {
    ref.onSnapshot(querySnapshot => {
        const items = []
        querySnapshot.forEach(doc => {
            items.push({ id: doc.id, data: doc.data() })
        })
        setGigs(items)
    })
}

With that you can then render both the data and the ID in your render method, and then pass the ID along to deleteGig.

Upvotes: 1

Related Questions