使用firebase函数,我每x分钟轮询一个API,以获取一组我保存在FireStore中的项目。 把每一项都说成这样:
{ name: "John", id: 1}
如果这是一个新文档,我希望将其存储在firestore中,并使用值为“new”的state
字段:
[1]: { name: "John", state: "New"}
但是,如果我以前看过这个文档(它在firestore中有那个id),我想更新里面的数据,但是保持状态不变,即
之前:
[1]: { name: "John", state: "Processed"}
之后:
[1]: {name: "UpdatedName", state: "Processed"}
我怎样才能做到这一点呢? 对于已经存在的文档,我可以使用MergeFields
SetOption来实现这一点,因此排除state字段--但不幸的是,随后到达的全新文档没有使用state:“new”
设置。
另一个选择是用firebase检查每个文档的id是否存在,但这似乎不太理想,而且很难实现(最后我在foreach循环中进行了多个查询)。 这大致就是我的代码:
const batch = db.batch();
response.data.items.forEach(item => {
const document = {
name: item.name
state: "New"
};
batch.set(
db.collection(collectionPath).doc(item.id),
document,
{
mergeFields: Object.keys(document).filter(
field => field !== 'state'
),
}
);
});
return batch.commit();
由于文档的新状态与文档的现有状态(或缺乏状态)有关,因此需要在这里执行事务。
let docRef = db.collection(collectionPath).doc(item.id);
let transaction = db.runTransaction(t => {
return t.get(docRef)
.then(doc => {
if (doc.exists()) {
t.update(docRef, { state: "Processed" });
}
else {
t.set(docRef, { name: "John", state: "New" });
}
});
}).then(result => {
console.log('Transaction success!');
}).catch(err => {
console.log('Transaction failure:', err);
});