如何使用Firebase构建数据,以允许数据是特定于用户且也是公共的?

如何使用Firebase构建数据,以允许数据是特定于用户且也是公共的?,firebase,firebase-realtime-database,firebase-security,Firebase,Firebase Realtime Database,Firebase Security,我们正在使用Firebase实时数据库构建一个平台,我正在努力找到最好的方法来构建我们的数据以供私人和公共访问 今天我们有 database: { items: { $userUid: { $itemUid: { poster_link: "..." format: "..." title: "..." } } } } 我们的所有物品都存储在每个用户的下方,以便快速安全地装载 我们的规则是这样制定的

我们正在使用Firebase实时数据库构建一个平台,我正在努力找到最好的方法来构建我们的数据以供私人和公共访问

今天我们有

database: {
  items: {
    $userUid: {
      $itemUid: {
        poster_link: "..."
        format: "..."
        title: "..."
      }
    }
  }
}
我们的所有物品都存储在每个用户的下方,以便快速安全地装载

我们的规则是这样制定的

{
  "rules": {
    "items": {
      "$userId": {
        "$itemId": {
          ".read": "auth !== null,
          ".write": "auth !== null"
        }
      }
    }
  }
}
database: {
  items: {
      $itemUid: {
        poster_link: "..."
        format: "..."
        title: "..."
        user: "userid"
      }
  }
}
因此,只有授权用户才能读取和写入数据。如果值为真,我可以创建类似的内容以允许项目公开:

".read": "auth !== null || data.child('public').val() == true"
但这仍然低于$userUid


因此,我想知道您是否对如何构造此示例有任何建议,以允许项目位于某个用户之下,并且在该用户之下也可以公开查看,这是不必要的,有点像您共享某些内容时Dropbox所做的那样。

您可以这样构造

{
  "rules": {
    "items": {
      "$userId": {
        "$itemId": {
          ".read": "auth !== null,
          ".write": "auth !== null"
        }
      }
    }
  }
}
database: {
  items: {
      $itemUid: {
        poster_link: "..."
        format: "..."
        title: "..."
        user: "userid"
      }
  }
}
现在将规则设置为

{
  "rules": {
    "items": {
        "$itemId": {
          ".read": "auth !== null || data.child('public').val() == true,
          ".write": "auth !== null"
        }
    }
  }
}

您选择的数据结构没有利用Firebase的平面数据原则。这将使您很难查询多个用户的项目。例如,如何在不深入每个用户的情况下获取所有公共项目

类似地,名为public的布尔值也不好,因为您无法将其扩展到其他ACL场景。更好的是一个可以在将来扩展的ACL对象

例如:

items: {
  itemsUid: { 
    [...],
    userId: ...,
    ACL: { public: true }
  }
}
现在您可以编写规则:

auth !== null && (root.child(items/ACL/public).exsists() || data.userId === auth.UID)

如果在三个月内,您添加了可以看到您的帖子的朋友或可以看到您的项目的关注者的概念,您只需向ACL对象添加
friends:true,followers:true
,并调整规则即可

最简单的解决方案是将公共数据和私有数据分开。请参见我关于为什么和如何的回答: