繁体   English   中英

Firebase 实时数据库 - 基于访问节点设置多个 .on() 侦听器

[英]Firebase Realtime Database - Set up multiple .on() listeners based on access nodes

我正在使用具有以下结构的 Firebase 实时数据库。 我希望获取用户有权访问的所有“笔记”并订阅这些笔记中的更改。

notes: {
  "noteId-1345" : {
    "access" : {
      "author": "1234567890"
        "members": {
          "1234567890": 0 <--- Author
          "0987654321": 1 <--- Member
        }
      },
    "data" : {
      "title": "Hello",
      "content": "Konichiwa!",
      "comment": "123"
    }
  }
}

(我知道理想情况下,这种结构可以更平坦。:))

要获取用户有权访问的所有笔记 - 我在根目录中保留一个额外的 user_notes 节点:每当我将用户( members更新)与笔记关联时,我都会更新/notes/$noteid/user_notes/$uid

user_notes: {
  "$uid": {
    "noteId-1345": {
      myHide: false,
      mySortOrder: 0,
      title: "Hello"
    }
  }
}

获取数据时,我希望订阅用户有权访问的所有笔记。

我首先获取用户有权访问的笔记的 id,然后附加侦听器以订阅每个note更新。

const uid = getState().auth.uid
let collectedNotes = {} 
...
database.ref(`user_notes/${uid}`).on('value', (myAccessSnaps) => {
  myAccessSnaps.forEach((accessSnap) => {
    const noteId = accessSnap.key
    const privateData = {'personalData': {...accessSnap.val()}}
    database.ref(`notes/${noteId}`).on('value', (noteSnap)=>{
      const notData = noteSnap.val()
      const fullData = { ...privateData, ...notData }
      const note = {
        id: noteSnap.key,
        ...fullData
      }
      collectedNotes[note.id] = note
      ...
    })
  }))
})

(当然,在设置新的监听器之前,我需要使用.off()来分离监听器)

这有点问题,因为我必须为每个note附加一个听众 - 并且数据库中可能有数百个音符。 这是最有效的方法吗? - 似乎效率低下。

有没有办法用一个听众收听用户在/notes路径中可以访问的所有笔记? 还是我的做法完全错误? :)

亲切的问候/K

在了解.on() 不返回承诺后- 我变得更容易解决我的问题。

附加很多.on()听众对我来说没有任何意义。

对我来说最简单的方法是:

1 -更新我的接入节点带有时间戳updatedAt每次注已更新

2 - 使用返回承诺的.once()加载初始数据,请参阅下面的代码。

3 - 为访问节点更改时设置单独的订阅

let myPromises = []
database.ref(`user_notes/${uid}`).once('value', (myAccessSnaps) => {
  myAccessSnaps.forEach((accessSnap) => {
    const noteId = accessSnap.key
    const privateData = {'personalData': {...accessSnap.val()}}
    myPromises.push(
      database.ref(`notes/${noteId}`).once('value', (noteSnap)=>{
        const notData = noteSnap.val()
        const fullData = { ...privateData, ...notData }
        const note = {
          id: noteSnap.key,
          ...fullData
        }
        collectedNotes[note.id] = note
        ...
      })
    )
  }))
})

return Promise.all(myPromises)
.then(() => {
  dispatch(setNotes(categories))
...
// Set up subscription after initial load
database.ref(`user_notes/${uid}`).on('value', (myAccessSnaps) => {
  ...
  // Use access node listener only - gets updated by 'updatedAt'
  database.ref(`notes/${noteId}`).once('value', (noteSnap)=>{
    //Collect and dispatch data

亲切的问候/K

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM