简体   繁体   English

如何使用 set 方法更新 Firestore 中的现有文档

[英]How to update existing document in firestore using set method

I have a firestore document that I want to update.我有一个要更新的 Firestore 文档。 Here's my code -这是我的代码 -

admin.firestore().collection('testResult').doc(`${testId}`).set(
            {
                name: userName,
                email: email,
            },
            { merge: true },
        );

I am using "set" method with "merge: true" object.我正在使用带有“合并:真”object 的“设置”方法。 As I want to create a new document if it doesn't exists and update the data if it exists.因为我想创建一个新文档,如果它不存在并更新数据,如果它存在。

The document that I am trying to update is getting rewritten by new property that I sent, rather than appending the data in the existing document.我尝试更新的文档正在被我发送的新属性重写,而不是在现有文档中附加数据。 I read that using {merge: true} will merge the incoming data with current data, but that's not working.我读到使用{merge: true}会将传入数据与当前数据合并,但这不起作用。 My whole document is being replaced by new data.我的整个文档正在被新数据取代。

Here's my firestore collection when I first create the document -这是我第一次创建文档时的 Firestore 集合 -

在此处输入图像描述

And here's the same document when I update it -当我更新它时,这是同一个文件 -

在此处输入图像描述

The update() method (or set() with a merge flag) creates a document that: update()方法(或带有合并标志的set() )创建一个文档:

  1. contains the value for fields that you specify.包含您指定的字段的值。
  2. any other fields that are already in the document.文档中已有的任何其他字段。

So for any field you specify, any existing value for that field in the document will be overwritten.因此,对于您指定的任何字段,文档中该字段的任何现有值都将被覆盖。

Given that knowledge, the result is working as expected.鉴于这些知识,结果按预期工作。


If you want to append the values you specify to the current value of that field, you'll need to use an atomic transaction to read-and-write the document.如果要将 append 指定的值更改为该字段的当前值,则需要使用原子事务来读写文档。

If you want to store multiple username+email combinations, you'll need to do so in an Array field.如果要存储多个用户名+电子邮件组合,则需要在 Array 字段中执行此操作。 You can then either add the new combination with a transaction again, or (if the combination of username+email has to be unique) you can use the atomic array-union operation然后,您可以再次将新组合添加到交易中,或者(如果用户名+电子邮件的组合必须是唯一的)您可以使用原子array-union操作

the merge doesn't create new FIELDS , it allows you to either ADD new fields that don't already exist or to selectively update specific fields. merge不会创建新的FIELDS ,它允许您添加尚不存在的新字段或选择性地更新特定字段。 Fieldnames are unique;字段名是唯一的; in your statement:在你的声明中:

admin.firestore().collection('testResult').doc(`${testId}`).set(
            {
                name: userName,
                email: email,
            },
            { merge: true },
        );

you are specifying the fields name and email , and EXACTLY AS THE COMMAND SAYS it is setting those fields to the new values.您正在指定字段nameemail ,并且正如命令所说,它将这些字段设置为新值。 If you had done:如果你做了:

admin.firestore().collection('testResult').doc(`${testId}`).set(
            {
                anotherName: userName,
                anotherEmail: email,
            },
            { merge: true },
        );

...it would have ADDED those fields (as in "merged new fields into the document") and left the existing fields name and email in-place ...它将添加这些字段(如“将新字段合并到文档中”)并将现有字段nameemail在原地

IF you had done:如果你做了:

admin.firestore().collection('testResult').doc(`${testId}`).set(
            {
                anotherName: userName,
                anotherEmail: email,
            },
            { merge: false },
        );

...(note merge: false) it would have set the DOCUMENT to ...(注意合并:假)它会将 DOCUMENT 设置为

            {
                anotherName: userName,
                anotherEmail: email,
            },

...ignoring the existing fields. ...忽略现有字段。

Remember, fieldnames are UNIQUE in a document - you WILL NOT SEE a document like so:请记住,字段名在文档中是唯一的 - 您不会看到这样的文档:

            {
                name: userName1,
                email: email1,
                name: userName2,
                email: email2,
                name: userName3,
                email: email3,
                name: userName4,
                email: email4,
            }

I strongly suggest you study the documentation quite a bit more and understand exactly how Firestore documents work .我强烈建议您多研究文档并准确了解 Firestore 文档的工作原理

I got it working by doing what Frank van Puffelen suggested.我按照 Frank van Puffelen 的建议去做了。 Here's the correct code if anyone needs this in future -如果将来有人需要,这是正确的代码-

admin
    .firestore()
    .collection('testResult')
    .doc(`${testId}`)
    .get()
    .then(doc => {
        if (doc.exists) {
            admin
                .firestore()
                .collection('testResult')
                .doc(`${testId}`)
                .update({
                    data: admin.firestore.FieldValue.arrayUnion(
                        { userName, email }
                    ),
                });
        } else {
            admin
                .firestore()
                .collection('testResult')
                .doc(`${testId}`)
                .set({
                    data: [{ userName, email }],
                });
            }
        return;
    })
    .catch(error => console.log(error));

First I checked if the document exists.首先我检查了文件是否存在。 If it doesn't exists then I am creating a new document and saving a object containing an array with my values.如果它不存在,那么我将创建一个新文档并保存一个包含我的值的数组的 object。 If it exists then I am updating the array.如果它存在,那么我正在更新数组。

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

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