对于上下文:我有一个cron-job.org,可以在我的firebase项目中触发https函数。
在此函数中,我必须遍历集合中的所有文档并更新计数器(每个doc可能具有不同的计数器值)。如果计数器达到限制,我将更新另一个集合(独立于第一个集合),并删除达到限制的文档条目。如果计数器未超出限制,我只需使用更新的计数器值更新doc条目。
我尝试调整文档中的示例,尝试使用事务,批处理,但我不确定如何继续。根据交易的描述,这是要走的路,但是示例只显示如何编辑单个文档。
这就是我所拥有的(尝试调整实时数据库样本):
function updateCounter() {
var ref = db.collection('my_collection_of_counters');
return ref.get().then(snapshot => {
const updates = {};
snapshot.forEach(child => {
var docData = child.data();
var newCounter = docData.counter+1;
if (newCounter == 10) {
// TO-DO: add to stock
updates[child.key] = null;
} else {
docData.counter = newCounter;
updates[child.key] = docData;
}
});
// execute all updates in one go and return the result to end the function
return ref.update(updates);
});
}
它不起作用,集合没有更新方法。更新集合中每个文档的最佳方法是什么?一个接一个?交易?有一个例子吗?
PS:updateCounter是https触发器调用的函数。 Cron +触发器工作正常。
修改 当一个项目达到阈值时,我想更新另一个独立于计数器的集合。嵌套事务是一个很好的解决方案吗?
修改后的代码:
function updateCounter() {
var ref = db.collection('my_collection_of_counters');
var transaction = db.runTransaction(t => {
return t.get(ref)
.then(snapshot => {
let docs = snapshot.docs;
for (let doc of docs) {
var item = doc.data();
var newCounter = item.counter + 1;
if (newCounter == 10) {
console.log("Update my_stock");
// ADD item.quantity to stock collection
}else{
t.update(doc.ref, {counter: newCounter});
}
}
});
})
.then(result => {
console.log('Transaction success');
})
.catch(err => {
console.log('Transaction failure:', err);
});
}
答案 0 :(得分:1)
正如您已经注意到的那样,您希望在事务中执行此操作,以确保您可以在单个操作中更新当前计数器值。您还可以在计数器达到其阈值后,在同一事务中创建新文档并删除现有文档。对于单个事务中的所有文档,我没有看到任何好处,因为每个文档的操作似乎与其他文档无关。
在Firestore交易中,您perform the operations on a Transaction
object as shown in the documentation。在你的情况下,你是
transaction.get()
获取当前文档。transaction.update()
将新计数器值写入数据库transaction.create
以在那里创建文档。transaction.delete
,将其删除。有关详情,建议您扫描reference documentation for the Transaction
class。