0
votes

I have a game which uses Firestore for keeping multiplayer saves.

Basically each document has this format ($denotes a 20 character p-random ID)

$savegame = {
  users = [$user1, $user2]  
  info = {turn: 2, }
  gamestate = {longjsonstring} 
} 

I query the data using

firebase.firestore().collection('savegamescollection').where('users', 'array-contains', firebase.auth().currentUser.uid)

I want to use firestore rules to only allow people in the game to update the save, I couldn't find a way to check the users array in firestore rules.

So what I did was ( > denotes a collection )

savegame = {
  > usercol = { $user1, $user2 }   - line A
  users = [user1, user2]           - line B
...
} 

I use the rule

match /savegamescollection/{doc} { 
allow read, write: if exists(/databases/$(database)/documents/savegamescollection/$(doc)/usercol/$(request.auth.uid));

This does work, but is buggy and ugly. I have the same data duplicated as elements in an array and as document ID's.

Is there a way to use one of these lines in the data structure (A and B above) to allow both the query and the rule to function.

Thanks

1
It's difficult to imagine the code and data you're working with based on what you have here so far. Please edit the question to show 1) the rules you're working with that don't work the way you expect, 2) the client query that you're trying to allow or deny, 3) some specific data that you're working with. - Doug Stevenson
I guess I am looking for a rules function which can search an array. Or a query which can condition on the id of a document inside the data I need (rather then the value of a document) Or another method to avoid the duplication, or clarification that the duplication is required as the query and rules structures are incompatible. - Paul Torrington

1 Answers

1
votes

If you want to enforce that a user must use an array-contains query to only request documents that the user's UID is listed in, you can use hasAny on the list field to check if their UID is in the list.

match /savegamescollection/{doc} {
  allow read, write: if resource.data.users.hasAny([request.auth.uid]);
}