javascript - 如何将项目存储在 firebase 列表中的特定位置

标签 javascript list firebase firebase-realtime-database

我有一个这样的列表:

{ 
  randomFirebaseGeneratedUID: {position: 0, someData: ''},
  randomFirebaseGeneratedUID: {position: 1, someData: ''},
  randomFirebaseGeneratedUID: {position: 2, someData: ''},
  randomFirebaseGeneratedUID: {position: 3, someData: ''},
  randomFirebaseGeneratedUID: {position: 4, someData: ''},
}

现在我想添加一个新项目,例如在位置 1 和 2 之间

我很难找到一种干净且正确的方法来做到这一点。我目前想到的是:

export const addAtListPositionHelper = (list, payload) => {
  Object.keys(list)
    .filter(key => list[key].position > payload.position)
    .forEach(key => {
      list[key].position = list[key].position + 1
    })
  list.push().set(payload)
  return list
}

export function addAtListPosition(contentId, payload) {
  const db = getFirebaseInstance().database()
  db.ref(`${contentId}`).transaction(list => addAtListPositionHelper(list, payload))
}

有效负载如下所示:{p: 2, someData: ''}

这样做的问题是,我无法像代码中编写的那样推送有效负载,因为列表实际上是一个对象,并且这些对象的 id 是从 firebase 生成的 UID。

当然,我可以自己生成 UID,但对我来说,有些 UID 是由 firebase 生成的,有些是我自己生成的,这看起来有点困惑。

我想到的另一种方法是先推送商品,然后再排序,但这可能会导致短时间内数据不一致。

真的没有更好的方法来处理我认为非常常见的用例吗?

最佳答案

这听起来很困惑,并且现在是由竞争条件造成的。在任何数据库上,重新索引都是一项昂贵的操作,尤其是在 Firebase 上,因为它具有 NoSQL/实时性质。

我能快速想到的唯一方法是在整个列表上使用事务。这会起作用,但会严重损害此代码的可扩展性。

问题源于这样一个事实:您希望您的位置是连续的整数,这是很难扩展的。事实上,最古老的 Firebase 博客文章之一恰恰建议反对这一点:Best Practices: Arrays in Firebase .

因此,为了使此操作更具可扩展性,您必须放弃连续整数的位置。我知道有两种方法:

  1. 使它们不连续

  2. 将它们设置为非整数

:-)

使它们不连续

另一种方法是在生成新文档时留出空间用于插入项目。例如。如果你像这样间隔索引:

{ 
  randomFirebaseGeneratedUID: {position: 0, someData: ''},
  randomFirebaseGeneratedUID: {position: 10, someData: ''},
  randomFirebaseGeneratedUID: {position: 20, someData: ''},
  randomFirebaseGeneratedUID: {position: 30, someData: ''},
  randomFirebaseGeneratedUID: {position: 40, someData: ''},
}

那么 10 到 20 之间的项目就可以获得位置 15。这实际上很常见,并且大大减少了重新索引所有项目的需要。

将它们设置为非整数

如果您的头寸可以是非整数,您将永远不需要重新索引。在 1 和 2 之间插入一个项目就是简单的 1.5。随着 float 的分辨率的提高,您不太可能很快用完“位置”。

这实际上是我最近需要移动/重新排序/插入文档时所采取的方法。

关于javascript - 如何将项目存储在 firebase 列表中的特定位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48701067/

相关文章:

javascript - Next.Js 带有样式组件的 React 应用程序。警告 : Prop `className` did not match. 服务器: "x"客户端: "y"

javascript - 在创建实例后通过 JavaScript 更新 CKEditor 的 CSS

c# - List.clear() 后跟 List.add() 不起作用

javascript - 如何拦截javascript中的innerHTML变化?

javascript - 检查禁用按钮是否不起作用

java - 双迭代器循环

python - list.sort(key=list.count) 在 Python 3.x 中如何工作?

firebase - 如何在 flutter 中解决 "RangeError (index): Invalid value : Valid value range is empty : 0"?

android - 如何检查firestore中是否已存在某些数据

swift - 如何从 Firebase 一次检索整个对象?