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

时间:2019-04-01 10:10:28

标签: javascript firebase google-cloud-firestore

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

因此,我想添加myObj,并且我希望文档的ID为myObj.id:

# I'd rather use a neutral name for the data, since `table` is a function name, see `?table`
dat <- structure(list(x = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), site = c(1, 
1, 1, 2, 2, 2, 3, 3, 3, 1), sp1 = structure(c(2L, 2L, 3L, 3L, 
1L, 1L, 3L, 3L, 3L, 1L), .Label = c("0", "1", "na"), class = "factor"), 
    sp2 = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 2L, 3L, 3L), .Label = c("0", 
    "1", "na"), class = "factor")), class = "data.frame", row.names = c(NA, 
-10L))

# first thing to do is make proper NAs!
levels(dat$sp1) <- levels(dat$sp2) <- c(0, 1, NA)

但是当我添加具有现有ID的新文档时,它没有覆盖错误,而是将其覆盖。

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

有没有办法做到这一点?

1 个答案:

答案 0 :(得分: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的{​​{3}}对象,如下(set()的摘录):

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);
    })

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