在 Firebase 中增加所有内容价值的最有效方法

Most efficient way to increment a value of everything in Firebase

假设我有这样的条目:

而且我想为估算列表中的每个项目将 priority 字段递增 1。

我可以这样获取估算值:

var estimates = firebase.child('Estimates');

在那之后,我如何将每个估计优先级自动递增 1?

这是遍历所有项目并提高其优先级的一种方法:

var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
  estimatesSnapshot.forEach(function(estimateSnapshot) {
    estimateSnapshot.ref().update({
      estimateSnapshot.val().priority + 1
    });
  });
});

它遍历 Estimates 的所有 children 并增加每个的优先级。

您也可以将调用合并为一个 update() 调用:

var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
  var updates = {};
  estimatesSnapshot.forEach(function(estimateSnapshot) {
    updates[estimateSnapshot.key+'/priority'] = estimateSnapshot.val().priority + 1;
  });
  estimatesRef.update(updates);
});

性能将与第一个解决方案相似(Firebase 在处理多个请求时非常高效)。但在第二种情况下,它将向服务器发送一个命令,因此它要么失败要么完全成功。

仅适用于 FIRESTORE API,不适用于 FIREBASE

感谢最新的 Firestore 补丁(2019 年 3 月 13 日),您无需按照上面的其他答案进行操作。

Firestore 的 FieldValue class 现在托管一个 increment 方法,该方法自动更新 firestore 数据库中的数字文档字段。您可以将此 FieldValue 标记与 set(合并选项为真)或 DocumentReference 对象的 update 方法一起使用。

用法如下(来自官方docs,仅此而已):

DocumentReference washingtonRef = db.collection("cities").document("DC");

// Atomically increment the population of the city by 50.
washingtonRef.update("population", FieldValue.increment(50));

如果您想知道,它可以从 firestore 的 18.2.0 版本获得。为了大家方便,Gradle依赖配置为implementation 'com.google.firebase:firebase-firestore:18.2.0'

Note: Increment operations are useful for implementing counters, but keep in mind that you can update a single document only once per second. If you need to update your counter above this rate, see the Distributed counters page.


编辑 1FieldValue.increment() 纯粹是 "server" 方面(发生在 firestore 中),因此您不需要将当前值暴露给客户。

编辑 2:在使用管理员 API 时,您可以使用 admin.firestore.FieldValue.increment(1) 实现相同的功能。感谢@Jabir Ishaq 自愿让我知道未记录的功能。 :)

EDIT 3:如果要increment/decrement的目标字段不是数字或不存在,则increment方法设置值到当前值!这在您第一次创建文档时很有用。