在 firebase 实时数据库中安全地使用递增数字作为键
Safely using incrementing number as key in firebase realtime database
我在 firebase 实时数据库中有一个路径,我想在其中使用递增键:
/foo/1 {a: "some data"}
/foo/2 {a: "some other data"}
现在,我正在查询最后一个 /foo/ 记录以获取最后一个数字,并将 /foo/3 设置为最新对象。然而,这是一种竞争条件——如果两个用户同时尝试这样做,可能会导致他们都创建 /foo/3(并且一个会覆盖另一个)。
有什么方法可以安全地做到这一点吗?看起来实时数据库对事务的支持有限,但我不确定它们是否可以用于此用例。
提前致谢!
编辑:这正是我目前正在做的事情
const fooCollection = await admin.database().ref("foo").limitToLast(1).get();
let lastFooId;
fooCollection.forEach(snapshot => {
lastFooId = snapshot.key
})
let newFooId = 0;
if(lastFooId) {
newFooId = parseInt(lastFooId) + 1;
}
await admin.database().ref(`/foo/${newOrderId}`).set(fooData);
有什么方法可以让这个交易成为 /foo/ 路径上的交易吗?
无法在 Firebase 实时数据库的事务内执行查询。
执行此操作的惯用方法是将计数器值保存在已知路径(在其他数据库中通常称为序列),而不是使用查询来确定其值 - 然后使用事务(或multi-path update) 将新值写入 sequence/value 和新节点。
这也将解决查询 even-growing 列表时固有的可伸缩性问题。即使该限制为数十万(或现在更可能:数百万)个节点,使用没有这种可扩展性限制的方法仍然更好。
我在 firebase 实时数据库中有一个路径,我想在其中使用递增键:
/foo/1 {a: "some data"}
/foo/2 {a: "some other data"}
现在,我正在查询最后一个 /foo/ 记录以获取最后一个数字,并将 /foo/3 设置为最新对象。然而,这是一种竞争条件——如果两个用户同时尝试这样做,可能会导致他们都创建 /foo/3(并且一个会覆盖另一个)。
有什么方法可以安全地做到这一点吗?看起来实时数据库对事务的支持有限,但我不确定它们是否可以用于此用例。
提前致谢!
编辑:这正是我目前正在做的事情
const fooCollection = await admin.database().ref("foo").limitToLast(1).get();
let lastFooId;
fooCollection.forEach(snapshot => {
lastFooId = snapshot.key
})
let newFooId = 0;
if(lastFooId) {
newFooId = parseInt(lastFooId) + 1;
}
await admin.database().ref(`/foo/${newOrderId}`).set(fooData);
有什么方法可以让这个交易成为 /foo/ 路径上的交易吗?
无法在 Firebase 实时数据库的事务内执行查询。
执行此操作的惯用方法是将计数器值保存在已知路径(在其他数据库中通常称为序列),而不是使用查询来确定其值 - 然后使用事务(或multi-path update) 将新值写入 sequence/value 和新节点。
这也将解决查询 even-growing 列表时固有的可伸缩性问题。即使该限制为数十万(或现在更可能:数百万)个节点,使用没有这种可扩展性限制的方法仍然更好。