Firebase Cloudstore:如何在集合中“全部更新”/“删除部分”文档?

时间:2018-01-15 16:13:01

标签: javascript firebase transactions google-cloud-firestore

对于上下文:我有一个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);
    });
}

1 个答案:

答案 0 :(得分:1)

正如您已经注意到的那样,您希望在事务中执行此操作,以确保您可以在单个操作中更新当前计数器值。您还可以在计数器达到其阈值后,在同一事务中创建新文档并删除现有文档。对于单个事务中的所有文档,我没有看到任何好处,因为每个文档的操作似乎与其他文档无关。

在Firestore交易中,您perform the operations on a Transaction object as shown in the documentation。在你的情况下,你是

  1. 使用transaction.get()获取当前文档。
  2. 从文件中获取计数器。
  3. 增加柜台。
  4. 如果新值低于您的阈值:
    1. 调用transaction.update()将新计数器值写入数据库
  5. 如果新值高于您的阈值:
    1. 在新集合上调用transaction.create以在那里创建文档。
    2. 在现有文档上调用transaction.delete,将其删除。
  6. 有关详情,建议您扫描reference documentation for the Transaction class