joshuaiz
joshuaiz

Reputation: 445

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?

Upvotes: 4

Views: 2121

Answers (3)

JAYAPRAKASH
JAYAPRAKASH

Reputation: 1

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')
    })
  }

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317372

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.

Upvotes: 3

joshuaiz
joshuaiz

Reputation: 445

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)

}

Upvotes: 2

Related Questions