带有推送对象的实时数据库规则

Realtime Database Rules with Pushed Objects

我有一个实时数据库,可以将以下结构的对象推送到数据库中。

Teams
- 0
-- Players
--- 0
---- ID
--- 1
---- ID
- 1
--- 0
---- ID
--- 1
---- ID

基本上是两支队伍,每支队伍最多两名选手,每名选手都有一个ID。保存游戏后,游戏对象将被推送到数据库。我能够从 /games/[unique-ID-generated-by-pushed]

获取游戏数据

目前,我所有的(经过身份验证的)用户都可以读取/games 下的所有数据。我想限制这一点:用户只能看到他们参与的游戏。

我按照自己的规则做到了这一点。

{
  "rules":
  {
    "games":
    {
      "$match_id":
      {
    ".read": "data.child('$match_id').child('teams').child('0').child('players').child('0').child('ID').val() == auth.uid ||
        data.child('$match_id').child('teams').child('0').child('players').child('1').child('ID').val() == auth.uid ||
        data.child('$match_id').child('teams').child('1').child('players').child('0').child('ID').val() == auth.uid ||
        data.child('$match_id').child('teams').child('1').child('players').child('1').child('ID').val() == auth.uid"
      },
    }
  }
}

它并不优雅,但在我查询 /games/[unique-ID] 时有效。我似乎没有从 /games 参考中获得任何 DataChanged 事件,但这正是我需要的。

知道如何从这里开始吗?或者甚至可能吗?

如果您只想允许该游戏中的玩家读取该游戏的权限,那么在您当前的数据结构中这样的内容就足够了:

{
  "rules": {
    "games": {
      "$match_id": {
      ".read": "data.child('teams/0/players/0/ID').val() == auth.uid ||
                data.child('teams/0/players/1/ID').val() == auth.uid ||
                data.child('teams/1/players/0/ID').val() == auth.uid ||
                data.child('teams/1/players/1/ID').val() == auth.uid"
      },
    }
  }
}

规则的变化:

  • child($match_id)好像是个错误,所以我删除了它。
  • 您可以将整个路径传递给 child,这样可以大大缩短规则。

如果您想要更简单的规则,请考虑保留一个(额外的)更简单的游戏所有玩家列表:

games
  gameid1
    players
      player1id: true
      player2id: true
      player3id: true
      player4id: true

那么读取规则可以是单子句:

{
  "rules": {
    "games": {
      "$match_id": {
      ".read": "data.child('players').child(auth.uid).exists()"
      },
    }
  }
}

本质上,在这种情况下,您是在用更简单的 code/rules 换取更复杂的数据。