在 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 列表时固有的可伸缩性问题。即使该限制为数十万(或现在更可能:数百万)个节点,使用没有这种可扩展性限制的方法仍然更好。