简体   繁体   中英

Error: Adding data in a map in Firestore but the the new data saves as an array inside the map instead of a field

I have this colorMap from firestore which is a map .

在此处输入图像描述

What I'm trying to do is add more data in the colorMap . Let's say I have these:

Green: 50

Black 50

Red 20

And I wanted to add Pink: 80 . But what my code currently does is, if I'll add Pink: 80 , the Pink becomes an array instead of a field. Also, there might be instances where I would need to add more colors and quantity in one submission (eg Pink: 80 , Yellow: 20 , Brown: 60 )

This is what happens when I save it in Firestore.

在此处输入图像描述

Expected output Once I'll add Black: 80 , it should be the same data types with the other colors as well.

Submitting in firestore:

  //converting colorList to colorMap (map)
  const colorMap = colorList.reduce(function (map, obj) {
    map[obj.color] = obj.colorStocks;
    return map;
  }, {});

  const colorSave = Object.keys(colorMap);
  const qty = Object.values(colorMap);

  const handleSubmit = (index) => async (e) => {
    e.preventDefault();

    const ref = doc(db, "products", state);
    await updateDoc(ref, {
      ...product[index],
      [`colorMap.${colorSave}`]: qty,
    });
    console.log("done");
  };

This is the console for the colorMap :

在此处输入图像描述

Form

 {colorList.map((singleColor, index) => (
                    <div key={index}>
                        <>
                            <>
                                <TextField
                                  label="Color"
                                  name="color"
                                  type="text"
                                  id="color"
                                  required
                                  value={singleColor.color}
                                  onChange={(e) => handleColorChange(e, index)}
                                />
                                <TextField
                                  label="Stocks"
                                  name="colorStocks"
                                  type="number"
                                  id="colorStocks"
                                  required
                                  value={singleColor.colorStocks}
                                  onChange={(e) => handleColorChange(e, index)}
                                />
                            </>
                        </>
                      </div>
                      <br />
                        //button to remove the row of the textfield
                    </div>
                  ))}
                    //button to add the row of the textfield

The Object.keys(colorMap) and Object.values(colorMap) will return arrays . So what you are providing in the updateDoc() method are not single values rather they are arrays. That is the reason why the value is stored as an array instead of a map.

Now let me explain this a bit further by taking an example -

I have taken a hard coded map for convenience.

If the map has only one object ie const data={'Pink':90} , then by running the following code as you did,

async function updateData() {
 
const data={'Pink':90};
const colorSave=Object.keys(data);
const qty=Object.values(data);
const document=doc(db,'collectionId','documentId');
await updateDoc(document,{[`colorMap.${colorSave}`]:qty});
}

will add the data in the Firestore like the following -

在此处输入图像描述

If you have more than one object in the map ie const data={'Pink':90,'Red':70} , then by running the above code as you did, will add the data in the Firestore like the following as colorSave is an array and also qty is an array. The field name will be the elements in colorSave separated by commas.

在此处输入图像描述

So the correct way to update the document here is to use a for loop and inside that update the document. The sample code will look something like following -

async function updateData() {
const data={'Pink':90,'Red':70};
const colorSaveArray=Object.keys(data);
const qtyArray=Object.values(data);
const document=doc(db,'collectionId','documentId');
for (let index = 0; index < colorSaveArray.length; index++) {
  const colorSave = colorSaveArray[index];
  const qty = qtyArray[index];
  await updateDoc(document,{[`colorMap.${colorSave}`]:qty});
}
}

The above code will update the document like the following as you want it to be -

在此处输入图像描述

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