【问题标题】:Firebase Database Rules to match rowFirebase 数据库规则以匹配行
【发布时间】:2017-07-03 15:05:30
【问题描述】:

我正在使用 Firebase 实时数据库。我有以下数据:

我也有规矩:

{
  "rules": {
      ".read": "auth != null",
      ".write": "auth != null",
      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

初始规则完美运行:

      ".read": "auth != null",
      ".write": "auth != null",

问题

以下2条规则无效。

      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

如您所见,为了测试这些规则,在第一条规则中,我设置了一个不可能的条件,即memberId1memberId2 都等于用户uid。结果,我预计它会失败。

如果我删除:

      ".read": "auth != null",
      ".write": "auth != null",

只要有:

      "chat": {
        "$key": {
            ".read": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid",         
            ".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"          
        }
      },

然后访问被拒绝。即使我将其更改为:

 "data.child('memberId1').val() === 'h6qQg5YfQveTaCyBEXwDMSJPqwk1' 

以下也被拒绝:

  "chat": {
    "Ko7w9XTtuRVN4p6CMp7": {
        ".read": true,   

问题

我应该如何构建规则以允许用户只能访问其uid 匹配memberId1memberId2 的行?

谢谢

更新

我有以下代码:

   findChats(): Observable<any[]> {
        return this.af.database.list('/chat/', {
            query: {
                orderByChild: 'negativtimestamp'
            }
        }).map(items => {
            const filtered = items.filter(
                item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
            );
            return filtered;
        });
    }

我的问题类似于this one。我尝试以下但没有成功:

{
  "rules": {
      "chat": {
        "$id": {
            ".read": true
        }
      },

【问题讨论】:

  • 你读得怎么样?请在您读取数据的地方添加代码。
  • 您好 adolfosrs,感谢您的回复。我在上面添加了一个更新,显示了我如何查询数据库。我的问题是我没有完整的 jsonpath(只有/chat/)吗?有没有办法用这个 jsonpath 实现这个规则?
  • 希望答案对您有所帮助。

标签: firebase firebase-realtime-database firebase-authentication


【解决方案1】:

Firebase 规则是原子的。因此,如果您尝试阅读/chat(这就是您当前正在做的事情),它只会检查/chat 分支规则。由于您在/chat 中没有任何规则,因此默认即不授予访问权限。因此,只有在您尝试阅读 /chat/chatId 时才会评估您的规则。

您可以采用的一种可能的解决方案是存储每个用户所属的聊天列表。因此,您可以保留当前的聊天分支,但在数据库中存储另一个分支,结构如下:

user_chats: {
    uid1: {
        chatId1: true,
        chatId2: false
    }
    uid2: ...
}

和规则:

"user_chats": {
   "$uid": {
       ".read": "auth.uid === $uid",
       ".write": "auth.uid === $uid"
   }
}

然后您可以保留您的chat 规则,就像您已经拥有它们一样,但首先从/user_chats/uid 获取数据,然后对于检索到的每个chatId,您需要阅读chat/chatId

【讨论】:

  • 感谢 adolfosrs,这对我来说很有意义,为什么它不起作用。也感谢您对潜在解决方案的建议。
  • 这是否意味着以下问题的答案不正确? (我当然不能按照他们的建议让它工作)stackoverflow.com/questions/37773478/…
  • 抱歉,您能更清楚地说明您认为不正确的地方吗?我认为您正在尝试比较不同的问题。
  • 抱歉,您是对的。我没有正确理解该链接中的问题。它与我的示例不同,因为它们不像我的那样受限于 jsonpath 查询。
  • 有没有办法在查询中加入通配符?例如this.af.database.list('/chat/$key/h6qQg5YfQveTaCyBEXwDMSJPqwk1', ...
猜你喜欢
  • 2017-07-15
  • 2017-04-30
  • 2021-12-12
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
相关资源
最近更新 更多