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

Javascript 添加具有特定ID的文档而不覆盖现有文档,javascript,firebase,google-cloud-firestore,Javascript,Firebase,Google Cloud Firestore,我正在尝试向Firestore添加一个具有自定义唯一ID的文档,因此set()似乎是一种方式,因为add()将自动生成ID。 我想要的是,如果我添加了一个具有现有ID的新文档,就会出现一个错误 因此,我想要添加myObj,并且我想要文档的id为myObj.id: db.collection(COLLECTION_NAME).doc(myObj.code) .set(myObj) .then(() => { console.log('SENT!'); })

我正在尝试向Firestore添加一个具有自定义唯一ID的文档,因此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的新文档时,它不会得到一个错误,而是会覆盖它

我考虑过使用DB规则,但我还是不太清楚。我只需要拒绝那个操作,但如果我想更新某个文档的字段,我应该能够这样做


有办法做到这一点吗?

在您的评论后更新:

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

我认为最好使用以下方法:

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);
});
如中所述,使用
set()
方法,“如果文档尚不存在,将创建它”


如果您想“更新某些(现有)文档的字段”,您应该为该方法提供一个对象,该对象带有
merge:true
,如下所示(摘录):

因此,在你的情况下:

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

请注意,该方法的区别在于,使用
update()
,“如果应用于不存在的文档,则更新将失败。”

对不起,可能是我不清楚?我不想向文档中添加新数据。如果ID为“1A2b3Cd”的新文档不存在,我想添加该文档;如果该文档存在,并且我尝试添加ID为“1A2b3Cd”的新文档,我想得到一个错误。建议的“merge:true”和“update()”根本不能满足我的需要。谢谢@Renaud给出的两个答案,对于回复太晚,我真的很抱歉。我刚刚尝试了你的解决方案,效果很好。问题是,对于每次插入,必须在每个集合之前进行GET,我相信,正如您所做的那样,最好在事务内部进行GET,而不是在事务外部进行GET。这是唯一的办法吗?这是Firestore的“缺陷”吗?@Rodrigo.A92谢谢您的反馈!在任何情况下(无论交易与否),您都必须了解该文档是否存在,因为如果该文档存在,您希望“不做任何事情”。最好是使用事务。你可以接受我的回答,如果你认为它解决了你的问题,请参阅。谢谢谢谢你的解释。我当然会接受的。它解决了我的问题,而我找不到任何其他方法来做到这一点。干杯
db.collection(COLLECTION_NAME).doc(myObj.code)
    .set(myObj, { merge: true })
    .then(() => {
      console.log('SENT!');
    })
    .catch(error => {
      console.error('Error: ', error);
    })