gpt4 book ai didi

Firebase RTD,原子 "move"... 从两个 "tables"删除和添加?

转载 作者:行者123 更新时间:2023-12-04 00:32:27 31 4
gpt4 key购买 nike

在 Firebase 实时数据库中,这是一个非常常见的事务性事物

  • “表”A - 将其视为“待定”
  • “表格”B - 将其视为“结果”

某些状态发生了,您需要将一个项目从 A 移动到 B。

所以,我当然是说这很可能是一个云功能。

显然,此操作必须是原子,并且您必须防范赛道效应等。

所以,对于项目 123456,你必须做三件事

  • 阅读 A/123456/
  • 删除A/123456/
  • 将值写入B/123456

所有原子操作,带锁。

简而言之,Firebase 实现这一目标的方法是什么?

  • 已经有了很棒的 ref.transaction 系统,但我认为它与这里无关。

  • 也许以变态的方式使用触发器?

IDK


对于在这里谷歌搜索的任何人来说,值得注意的是令人难以置信的新 Firestore(很难想象还有什么比传统的 Firebase 更令人难以置信的,但你已经拥有它......),新的 Firestore系统内置 .......

enter image description here

这个问题是关于传统的 Firebase Realtime 的。

最佳答案

Gustavo 的回答允许通过单个 API 调用进行更新,该调用要么完全成功,要么失败。而且由于它不必使用事务,因此争用问题要少得多。它只是从要移动的键中加载值,然后写入单个更新。

问题是有人可能同时修改了数据。所以你需要使用安全规则来捕捉这种情况并拒绝它。所以配方变成了:

  1. 读取源节点的值
  2. 在单个 update() 调用中将值写入新位置,同时删除旧位置
  3. 安全规则验证操作,接受或拒绝它
  4. 如果被拒绝,客户端从#1 开始重试

这样做实质上是使用客户端代码和(一些公认的棘手的)安全规则重新实现 Firebase 数据库事务。

为了能够做到这一点,更新变得有点棘手。假设我们有这样的结构:

"key1": "value1",
"key2": "value2"

我们想将 value1key1 移动到 key3,那么 Gustavo 的方法将发送这个 JSON:

ref.update({
"key1": null,
"key3": "value1"
})

何时可以使用这些规则轻松验证此操作:

".validate": "
!data.child("key3").exists() &&
!newData.child("key1").exists() &&
newData.child("key3").val() === data.child("key1").val()
"

言外之意:

  • 当前 key3 中没有值。
  • 更新后key1没有值
  • key3的新值是key1的当前值

这很好用,但不幸的是,这意味着我们要在规则中对 key1key3 进行硬编码。为了防止对它们进行硬编码,我们可以将键添加到我们的更新语句中:

ref.update({
_fromKey: "key1",
_toKey: "key3",
key1: null,
key3: "value1"
})

不同的是,我们添加了两个已知名称的键,以指示移动的来源和目的地。现在有了这个结构,我们拥有了所有需要的信息,我们可以通过以下方式验证移动:

".validate": "
!data.child(newData.child('_toKey').val()).exists() &&
!newData.child(newData.child('_fromKey').val()).exists() &&
newData.child(newData.child('_toKey').val()).val() === data.child(newData.child('_fromKey').val()).val()
"

读起来有点长,但每一行的意思和之前一样。

在客户端代码中我们会这样做:

function move(from, to) {
ref.child(from).once("value").then(function(snapshot) {
var value = snapshot.val();
updates = {
_fromKey: from,
_toKey: to
};
updates[from] = null;
updates[to] = value;
ref.update(updates).catch(function() {
// the update failed, wait half a second and try again
setTimeout(function() {
move(from, to);
}, 500);
});
}
move ("key1", "key3");

如果您想尝试这些规则的代码,请查看:https://jsbin.com/munosih/edit?js,console

关于Firebase RTD,原子 "move"... 从两个 "tables"删除和添加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49032841/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com