添加具有特定ID的文档而不覆盖现有ID

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了添加具有特定ID的文档而不覆盖现有ID相关的知识,希望对你有一定的参考价值。

我正在尝试将自定义唯一ID的文档添加到Firestore,因此set()似乎就是这样,因为add()会自动生成ID。我想要的是,如果我添加一个具有现有ID的新文档,则会出现错误。

所以,我想添加myObj,我希望文档的id为myObj.id:

db.collection(COLLECTION_NAME).doc(myObj.code)
    .set(myObj)
    .then(() => {
      console.log('SENT!');
    })
    .catch(error => {
      console.error('Error: ', error);
    })

但是当我添加一个带有现有ID的新文档时,它会覆盖它而不是出错。

我考虑过使用数据库规则,但对我来说仍然不太清楚。我将需要拒绝该操作,但如果我想更新某个文档的字段,我应该能够做到这一点。

有办法实现吗?

答案

在评论后更新:

您的要求是“我想添加一个带有ID的新文档:'1A2b3Cd'如果它不存在,如果它存在并且我尝试添加一个ID为'1A2b3Cd'的新文档,我想得到一个错误。”

我认为最好的是使用transaction如下:

var docRef = db.collection(COLLECTION_NAME).doc(myObj.code);

return db.runTransaction(function(transaction) {
    return transaction.get(docRef).then(function(doc) {
        if (doc.exists) {
            throw "Document already exists!";
        }

        transaction.set(docRef, myObj);
    });
}).then(function() {
    console.log("Transaction successfully committed!");
}).catch(function(error) {
    console.log("Transaction failed: ", error);
});

正如doc中详述的那样,使用set()方法,“如果文档尚不存在,则会创建它”。


如果你想“更新某个(现有)文档的字段”,你应该向SetOptions方法提供merge: true对象set(),如下所示(doc的摘录):

var cityRef = db.collection('cities').doc('BJ');

var setWithMerge = cityRef.set({
    capital: true
}, { merge: true });

所以,在你的情况下:

db.collection(COLLECTION_NAME).doc(myObj.code)
    .set(myObj, { merge: true })
    .then(() => {
      console.log('SENT!');
    })
    .catch(error => {
      console.error('Error: ', error);
    })

请注意,与update()方法的不同之处在于,使用update()时,“如果应用于不存在的文档,则更新将失败”。

以上是关于添加具有特定ID的文档而不覆盖现有ID的主要内容,如果未能解决你的问题,请参考以下文章

如何通过本机反应将新字段数据更新到现有文档而不覆盖firebase-9中的现有数据

如何将具有自定义 ID 的文档添加到 Firestore

向 tar 文件添加条目而不覆盖其现有内容

ASP.NET 身份:尝试添加具有现有 ID 的用户

如何在 Swift 上将具有自定义 ID 的文档添加到 Firebase (Firestore)

合并两个数组而不覆盖[重复]