Firebase Realtime Rules - Предоставить доступ, когда какой-то дочерний элемент содержит значение x? - PullRequest
1 голос
/ 05 февраля 2020

Я пытался заставить это правило работать какое-то время, и я просто не могу понять его.

Структура моих данных следующая:

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

Так что в основном у меня есть игры, в которых каждая игра имеет уникальный идентификатор и содержит следующие данные: код игры, список игроков и некоторые другие данные. Проблема в том, что я хочу, чтобы только игроки из списка игроков в игре имели доступ для чтения ВСЕХ игроков этой игры, а не только самих себя.

Я думаю, что для этого требуется какой-то второй подстановочный знак, но я Кажется, я не могу найти, возможно ли это в правилах Firebase.

Вот то, что я придумал, и это наиболее близко подходит к решению:

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

Это не работает Возможно, потому что он использует $ uid в качестве фактического идентификатора вместо подстановочного знака. Когда я заменяю его фактическим ключом плеера, он работает.

Кто-нибудь знает, если и как я могу это сделать? Заранее спасибо.

РЕДАКТИРОВАТЬ:

Я остановился на использовании UID в качестве фактических ключей для игроков и использование data.child (auth.uid) .exists (), чтобы проверить, существует ли игрок .

1 Ответ

1 голос
/ 05 февраля 2020

Я не думаю, что вы можете использовать такой подстановочный знак.

Одним из решений будет ручной поиск «везде», например:

"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()"

(я не проверял их, обратите внимание на опечатки)

...