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

问题描述 投票:1回答:1

我正在尝试将自定义唯一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的新文档时,它会覆盖它而不是出错。

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

有办法实现吗?

javascript firebase google-cloud-firestore
1个回答
2
投票

在评论后更新:

您的要求是“我想添加一个带有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()时,“如果应用于不存在的文档,则更新将失败”。

© www.soinside.com 2019 - 2024. All rights reserved.