Paul Torrington
Paul Torrington

Reputation: 118

Firestore rules, queries and structuring data

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

Upvotes: 0

Views: 45

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317322

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]);
}

Upvotes: 1

Related Questions