首页 > 解决方案 > Firebase 实时数据库 - 仅获取我所属的节点

问题描述

我有一个具有以下结构的 Firebase 实时数据库。

notes
   noteId-1345
      access
         author: 1234567890
         members
             1234567890: 0 <--- Author
             0987654321: 1 <--- Member
      data
         title

使用以下代码获取数据时,我只能获得可以访问的“注释”。

database.ref('notes')
  .orderByChild(`access/members/${uid}`)
  .equalTo(0)
  .on('value', (snaps) => {

我希望通过使用下面的代码获得我是作者或成员的“注释”。但这会导致获得所有笔记,即使是我既不是作者也不是(?)

database.ref('notes')
  .orderByChild(`access/members/${uid}`)
  .endAt(99)
  .on('value', (snaps) => {

我的数据库规则是:

"notes": {
  //Indexes
  ".indexOn": ["data/title", "access/author", "access/members"],
  
  //entry-level access
  ".read": "
    auth.uid !== null && query.endAt === 99
  ",
  "$note_id": {
    ".write": "        
            //Create new if authenticated
            !data.exists() && auth.uid !== null
            //Update if author or member
      ||(data.exists() && newData.exists() && data.child('access/members').child(auth.uid).exists())
            //Delete if author
            ||(data.exists() && !newData.exists() && data.child('access').child('author').val() === auth.uid)        
    ",      
    "data": {
      //access
      ".read": "
        //if author or assigned user
        data.parent().child('access').child('author').val() === auth.uid ||
        data.parent().child('access/members').child(auth.uid).exists()
      ",
      ".write": "
        //if author or assigned user
        data.parent().child('access').child('author').val() === auth.uid ||
        data.parent().child('access/members').child(auth.uid).exists()          
      "          
    },
    "access" : {
      //access
      ".read" : "
        (auth.uid !== null) &&
        (
          data.child('author').val() === auth.uid
        ||
          data.child('members').child(auth.uid).exists()
        )
      "
    }

这是这种预期的行为还是我做错了什么?

亲切的问候/K

更新:

如果将我的访问规则更改为

  //entry-level access
  ".read": "auth.uid !== null && query.startAt === 0

和我的代码

database.ref('notes')
  .orderByChild(`access/members/${uid}`)
  .startAt(0)
  .on('value', (snaps) => {

一切似乎都在工作!

我有点担心我的访问规则允许用户阅读所有“笔记”,因为第一个代码使用.endAt(99)获取的所有“笔记”。

我如何确保用户只能阅读被列为作者或成员的“注释”?

亲切的问候/K

标签: javascriptfirebase-realtime-database

解决方案


您当前的数据结构可以轻松找到特定节点的所有者和成员。但是,查找特定用户的注释并不容易,而这正是您现在正在尝试做的事情。

像往常一样使用 NoSQL 数据库时,您可以通过扩展数据模型来解决这个问题。例如,为了允许为用户查找笔记,我会user_notes在根目录中保留一个额外的节点:

user_notes: {
  "$uid": {
    "noteId-1345": true
  }
}

因此,现在每当您将用户与注释相关联时,您都会在/notes/$noteid和 中写入该关系/user_notes/$uid。然后您可以使用这种双重数据结构在两个方向上执行查找。

另见:


推荐阅读