简体   繁体   English

错误:在 Firestore 的 map 中添加数据,但新数据保存为 map 中的数组而不是字段

[英]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 .我有来自 firestore 的这个colorMap ,它是一个map

在此处输入图像描述

What I'm trying to do is add more data in the colorMap .我要做的是在colorMap中添加更多数据。 Let's say I have these:假设我有这些:

Green: 50绿色:50

Black 50黑50

Red 20红20

And I wanted to add Pink: 80 .我想添加Pink: 80 But what my code currently does is, if I'll add Pink: 80 , the Pink becomes an array instead of a field.但是我的代码目前所做的是,如果我添加Pink: 80Pink将变成一个数组而不是一个字段。 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 )此外,在某些情况下,我可能需要在一次提交中添加更多 colors 和数量(例如Pink: 80 , Yellow: 20 , Brown: 60

This is what happens when I save it in Firestore.这是我将它保存在 Firestore 中时发生的情况。

在此处输入图像描述

Expected output Once I'll add Black: 80 , it should be the same data types with the other colors as well.预期 output一旦我添加Black: 80 ,它也应该是与其他 colors 相同的数据类型。

Submitting in firestore:在 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 :这是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 . Object.keys(colorMap)Object.values(colorMap) 将返回 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.因此,您在updateDoc()方法中提供的不是单个值,而是 arrays。这就是为什么将值存储为数组而不是 map 的原因。

Now let me explain this a bit further by taking an example -现在让我举个例子进一步解释一下 -

I have taken a hard coded map for convenience.为了方便起见,我采用了硬编码 map。

If the map has only one object ie const data={'Pink':90} , then by running the following code as you did,如果 map 只有一个 object 即const data={'Pink':90} ,那么像你一样运行下面的代码,

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 -将像下面这样在 Firestore 中添加数据 -

在此处输入图像描述

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.如果您在 map 中有多个 object 即const data={'Pink':90,'Red':70} ,那么通过像您一样运行上面的代码,将像下面这样将数据添加到 Firestore 中作为colorSave是一个数组,而且qty也是一个数组。 The field name will be the elements in colorSave separated by commas.字段名称将是colorSave中的元素,以逗号分隔。

在此处输入图像描述

So the correct way to update the document here is to use a for loop and inside that update the document.所以在这里更新文档的正确方法是使用 for 循环并在其中更新文档。 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 -上面的代码将按照您的意愿更新文档,如下所示 -

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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