Firebase实时规则-当某些子项包含值x时授予访问权限?

时间:2020-02-05 08:33:17

标签: firebase firebase-realtime-database firebase-security

一段时间以来,我一直在努力使这条规则生效,但我似乎无法弄清楚。

我的数据结构如下:

 games { 
    *gameid* {
        gamecode: *some gamecode*
        players {
           0 {
              playerId: *some playerid*
             }
           1 {
              playerId: *some playerid*
             }
           etc.
        }
        etc.
    }

所以基本上我有一些游戏,其中每个游戏都有一个唯一的ID,并包含以下数据:游戏代码,玩家列表和更多数据。问题是我只希望游戏玩家列表中的玩家有权读取该游戏的所有玩家,而不仅是他们自己。

我认为这需要某种第二通配符,但我似乎无法找到在Firebase规则中是否可行的方法。

这是我想出的最接近解决方案的方法:

"games": {
      "$gid": {
        "players": {
            ".read": "auth.uid != null && data.child('$uid').child('playerId').val() === auth.uid",
            ".write": false
        }
      }
    } 

这不起作用,可能是因为它使用'$ uid'作为实际ID而不是通配符。当我用播放器的实际钥匙代替它时,它确实可以工作。

有人知道我是否以及如何做吗?预先感谢。

编辑:

我决定使用uid作为玩家的实际键,并使用data.child(auth.uid).exists()来检查玩家是否存在。

1 个答案:

答案 0 :(得分:1)

我认为您不能使用这样的通配符。

一种解决方案是手动查找“无处不在”,就像这样:

"auth.uid == data.child('0/playerId').val() ||
 auth.uid == data.child('1/playerId').val() ||
 auth.uid == data.child('2/playerId').val()" // up to max allowed players

或者您可以将数据结构修改为如下形式:

 games { 
    *gameid* {
        gamecode: *some gamecode*
        players {
           0 {
              playerId: *some playerid*
             }
           1 {
              playerId: *some playerid*
             }
           etc.
        }
        playerIds {
           somePlayerId: true
           someOtherPlayerId: true
        }
    }

所以您可以简单地做

"data.parent().child('playerIds/'+auth.uid).exists()"

无需彻底更改代码(您仍将players用作数组)。

或者您可以完全放弃阵列:

 games { 
    *gameid* {
        gamecode: *some gamecode*
        players {
           somePlayerId {
              index: 0
              playerId: *some playerid*
             }
           someOtherPlayerId {
              index: 1
              playerId: *some other playerid*
             }
           etc.
        }
    }

规则变为

"data.child(auth.uid).exists()"

(我尚未测试过这些,请注意输入错误)