Reputation: 35
I have been trying to get this rule to work for some time now and I just don't seem to be able to figure it out.
The structure of my data is as follows:
games {
*gameid* {
gamecode: *some gamecode*
players {
0 {
playerId: *some playerid*
}
1 {
playerId: *some playerid*
}
etc.
}
etc.
}
So basically I have games, where every game has a unique id and contains the following data: gamecode, a list of players and some more data. The problem is that I want only the players in the players list of the game to have access to read ALL the players of that game, so not only themselves.
I think this requires some sort of second wildcard but I can't seem to find if this is possible in firebase rules.
Here is what I have come up with that gets the closest to being the solution:
"games": {
"$gid": {
"players": {
".read": "auth.uid != null && data.child('$uid').child('playerId').val() === auth.uid",
".write": false
}
}
}
This does not work, probably because it uses '$uid' as the actual id instead of a wildcard. When I replace it with the actual key of the player, it does work.
Does anyone know if and how I can do this? Thanks in advance.
EDIT:
I settled on using the uid's as actual keys for the players and using data.child(auth.uid).exists() to check if the player exists.
Upvotes: 1
Views: 266
Reputation: 3067
I don't think you can use such a wildcard.
One solution would be to manually look "everywhere", like this:
"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
Or you can modify your data structure to something like this:
games {
*gameid* {
gamecode: *some gamecode*
players {
0 {
playerId: *some playerid*
}
1 {
playerId: *some playerid*
}
etc.
}
playerIds {
somePlayerId: true
someOtherPlayerId: true
}
}
so you can simply do
"data.parent().child('playerIds/'+auth.uid).exists()"
without changing your code drastically (you'd still be using players
as array).
Or you can ditch the array completely:
games {
*gameid* {
gamecode: *some gamecode*
players {
somePlayerId {
index: 0
playerId: *some playerid*
}
someOtherPlayerId {
index: 1
playerId: *some other playerid*
}
etc.
}
}
and the rule becomes
"data.child(auth.uid).exists()"
(I haven't tested these, look out for typos)
Upvotes: 1