简体   繁体   中英

Remove item by key/value from Firestore array

I have an array in Firestore that is structured like this:

palettes
    0: {date: 2019-05-01, name: "First Palette", palette: [array]}
    1: {date: 2019-05-02, name: "Palette 2", palette: [array]

Each item in the palettes array is a palette item with date, name, and the palette data in an array.

In my React application, I'm trying to delete a specific palette in the Firestore db by referencing its name value and not having any luck.

For example, if I have the paletteName "Palette 2" passed in from a click event, how can I delete the palette with that string as the name value?

Here's what I've tried:

1.

const deletePalette = paletteName => {
    db.collection('users').doc(user.uid)
    .update({
         palettes: firebase.firestore.FieldValue.arrayRemove({
             name: paletteName
         })
    })
    // ...
}

2.

const deletePalette = paletteName => {
    db.collection('users').doc(user.uid)
        .update({
            palettes: firebase.firestore.FieldValue.arrayRemove(paletteName)
        })
    // ...
}

3.

const deletePalette = paletteName => {
    const ref = db.collection('users').doc(`${user.uid}/palettes/`)

    ref.update({
        [paletteName]: firebase.firestore.FieldValue.delete()
    })
    // ...
}

4.

const deletePalette = paletteName => {
    db.collection('users').doc(user.uid)
    .update({
        palettes: palettes.filter(
            palette => palette.name !== paletteName
        )
    })
    // ...
}

None of these are doing it. What am I missing here?

You won't be able to use FieldValue.arrayRemove . That only works for top level fields that are arrays. You also won't be able to do this in a single operation.

You will have to

1) read the entire document into memory,
2) modify the array in memory the way you want,
3) then update the field back to the document.

Thanks @Doug that helped.

It was pretty easy in the end. I already had a ref to the doc in my app state so from there, all I needed was this:

const deletePalette = paletteName => {
    // currentUser was in my app state and contains the user `doc` data
    // so just grab the palettes
    const userPalettes = currentUser.palettes

    // filter the palettes array
    const newPalettes = userPalettes.filter(
        palette => palette.name !== paletteName
    )

    // update the doc with the filtered palettes
    var userRef = db.collection('users').doc(user.uid)
    userRef.update({
        palettes: newPalettes
    })

    // update my state to reload user data
    setPaletteRemoved(true)

}
Cart = (ID) => {
    const x = {
      pname:'masala',
      price:22,
      data:1596960784777
    }

    this.db.doc(`${ID}`).update({
      cart: firebase.firestore.FieldValue.arrayRemove(x)
    }).then(() => {
      console.log('posted')
    })
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM