我在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/