我在Firebase实时数据库中有一组项目。客户端订阅数据库/items路径中的修改。但这具有每次添加,更新或删除单个项目时将所有项目发送到客户端的效果。仅仅由于一个项目文本已更新为一个字符,最多可能将1000个项目发送给客户端。

此代码有效,但不符合我想要的方式:

export const startSubscribeItems = () => {
  return (dispatch, getState) => {
    return new Promise(resolve => {
      database.ref('items')
      .orderByChild(`members/${uid}`)
      .equalTo(true)
      .on('value', (snapshot) => {
        let items = []
        snapshot.forEach( (childSnap) => {
          const id = childSnap.key
          const item = {id, ...childSnap.val()}
          items.push(item)
        })
        dispatch(setItems(items))
        resolve()
      })
    })
  }
}


我希望通过仅发送已更新的项目(同时保留客户端订阅)来使此网络更具成本效益。

我最初的想法是为每个项目实施订阅:

export const startSubscribeSingleItems = () => {
  return (dispatch, getState) => {
    return new Promise(resolve => {
      database.ref('items')
      .orderByChild(`access/members/${uid}`)
      .equalTo(true)
      .once('value', (snapshot) => {
        let items = []
        snapshot.forEach( (childSnap) => {
          const id = childSnap.key
          const item = {id, ...childSnap.val()}
          items.push(item)
          // .:: Subscribe to single item node ::.
          database.ref(`items/${id}`).on('value', (snap)=>{
             // Some logic here to handle updates and deletes (remove subscription)
          })
        })
        dispatch(setItems(items))
        resolve()
      })
    })
  }
}


这似乎有点麻烦,只能处理更新和删除。它不处理其他客户添加的情况。添加必须通过单独的数据库节点进行(例如'subscriptionAdditions //')吗?另外,由于首次加载读取所有项目,因此初始加载将必须清除“ subscriptionAdditions //”中的所有项目。

再次,麻烦。 :/

结论;是否有一种简单和/或推荐的方式来实现在考虑多个客户的情况下订购单个商品?

亲切的问候/ K

最佳答案

Firebase Realtime Database在服务器上的JSON结构与观察该状态的客户端之间同步状态。

就我所看到的大部分关于状态的最新更改而言,您似乎只想同步该状态的一个子集。在这种情况下,请考虑对数据库中的状态更改本身进行建模。

随着您更多地使用NoSQL数据库,您会发现修改数据模型以允许每个用例非常普遍。



例如,如果仅需要已更改节点的当前状态,则可以向每个节点添加lastUpdated时间戳属性。然后,您可以使用以下命令仅查询更新节点:

database.ref('items')
  .orderByChild('lastUpdated')
  .startAt(Date.now())


如果您希望自客户端上次联机以来一直在监听更改,则需要将它们上次联机的时间戳存储在某个地方,并使用它代替Date.now()



如果要同步所有状态更改,即使同一节点已更改多次,则也需要将每个状态更改存储在数据库中。通过使用按时间顺序排列的键(例如由push()生成的键)或为每个键存储时间戳,可以使用与以前相同的逻辑来仅读取尚未处理客户端的状态更改。



另请参阅:


NoSQL data modeling
How to only get new data without existing data from a Firebase?
Retrieve only childAdded from firebase to my listener in firebase

关于javascript - Firebase Realtime数据库-仅订阅单个添加,更新,删除,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61059672/

10-12 04:14
查看更多