【问题标题】:Most efficient way to increment a value of everything in Firebase在 Firebase 中增加所有内容的最有效方法
【发布时间】:2016-03-31 06:15:51
【问题描述】:

假设我有如下所示的条目:

我想为 Estimates 列表中的每个项目将 priority 字段增加 1。

我可以像这样获取估算值:

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

在那之后,我如何将每个 Estimates 优先级自动增加 1?

【问题讨论】:

  • 您尝试过什么了吗? firebase 文档还不错,可以帮助您入门。本指南只需几个小时即可为您节省大量时间:firebase.com/docs/web/guide
  • 在下面回答。对于下一个问题:显示您已经尝试过的内容,并且不要包含文本屏幕截图。您可以从 Firebase 仪表板导出 JSON 并将其包含为文本,这使我们更容易在答案中重复使用(并在找出答案时使用)。

标签: angularjs firebase firebase-realtime-database


【解决方案1】:

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

感谢最新的 Firestore 补丁(2019 年 3 月 13 日),您无需遵循上述其他答案。

Firestore 的 FieldValue 类现在托管一个 increment 方法,该方法可以自动更新 firestore 数据库中的数字文档字段。您可以将此 FieldValue 标记与 set(mergeOptions 为 true)或 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'

注意:增量操作对于实现计数器很有用,但是 请记住,您每次只能更新一个文档一次 第二。如果您需要更新您的计数器高于此速率,请参阅 Distributed counters页面。


编辑 1FieldValue.increment() 纯粹是“服务器”端(发生在 Firestore 中),因此您不需要向客户端公开当前值。

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

编辑3:如果你要递增/递减的目标字段不是数字或不存在,increment 方法将值设置为当前值!这在您第一次创建文档时很有帮助。

【讨论】:

  • 我可以在python中使用admin_sdk吗?
  • 哦,嗨。我在 admin-sdk 中没有看到任何这样的方法。我想你应该只使用DocumentReference.update() (the update method),因为你已经在一个受信任的环境中运行你的代码......目前,admin-sdk 中没有increment 方法......(到目前为止正如我搜索的那样!)
  • 对于admin sdk,代码有一点改动admin.firestore.FieldValue.increment(1)供参考(firebase.google.com/docs/reference/admin)
  • @JabirIshaq 嘿,感谢您的回复。我检查了firebase.google.com/docs/reference/admin/node/… 的页面,但找不到increment 方法文档!它是否存在但尚未在网络文档中更新? :P
  • @varun 是的,它不存在,但我试过了,令人惊讶的是它对我有用!谢谢
【解决方案2】:

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

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

它循环遍历Estimates 的所有孩子并增加每个孩子的优先级。

您还可以将调用合并为一个 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 在处理多个请求时非常高效)。但是在第二种情况下,它将向服务器发送一个命令,因此它要么失败,要么完全成功。

【讨论】:

  • 您能否为您的纯代码答案添加一些解释?它是in the VLQ queue,但由于它确实试图回答这个问题(从它的外观来看),它可能不应该在那里。
  • 这应该在firebase 3上工作吗?看来它不喜欢estimateSnapshot.val().priority + 1 语句....
  • 我很确定该声明没有任何改变。如果您有问题,请通过minimal code that reproduces the problem 发布问题,我们可以看看。
  • 问题出在estimateSnapshot.key()。从 firebase 3 开始,它不是一种方法,而是一种价值。所以只需删除括号:estimateSnapshot.key
猜你喜欢
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
相关资源
最近更新 更多