TL;DR - I'm writing data to my Firestore backend then attempting to get that data straight away. This works on some attempts but fails on others and it seems like there is some lag between the data being written and it being available to the exists() security method.
The Long Version
It's a big ask but after days of frustration I have managed to condense my issue into a JSBin example. If you can spare a few minutes to set up a Firestore instance and test this for me I would LOVE IT if someone can help fix this problem.
SETUP (Sorry, there isn't much)
If you got this far I'm assuming you have a Firebase account and can easily do the following...
- Set up a Firebase project with Firestore database
- In the Authentication > Sign-in Method section, enable Email/Password
Once this is done, in the Database > Rules section add the following rules:
service cloud.firestore {
match /databases/{database}/documents {
match /appUsers/{user} {
allow read, write: if user == request.auth.uid;
match /{children=**} {
allow read, write: if user == request.auth.uid;
}
}
match /groups/{group}{
allow create: if request.auth != null;
allow read, write:if exists(/databases/$(database)/documents/groups/$(group)/linkedUsers/$(request.auth.uid));
match /{children=**}{
allow create: if request.auth != null;
allow read, write:if exists(/databases/$(database)/documents/groups/$(group)/linkedUsers/$(request.auth.uid));
}
}
match /currencies/{currency}{
allow read: if request.auth != null;
}
}
}
With this done grab your config snippet and paste it in to my JSBin build below - you'll see the config object at the top of the JS file. Run this now and log in with an email and password - you will see the user appear in your new database.
The Problem
Enter a name in the first input field and click Add Group. This creates a group in your database and links it to the user and vice-versa.
The security rules you added above should allow access to a group if the ID of the user requesting the data is on the requested group's linkedUsers sub-collection (check the structure in your database to see this link is in place for each group you create).
As soon as the group is created I try to retrieve the new group data but this only works about 60% of the time. The rest of the time it fails with a Missing or insufficient permissions error. Try creating a few groups and some of them will be immediately and successfully queried while others fail.
All the data is being created - you can look in the database and see it and the fact that I can sometimes get it suggests to me there is something fruity going on and basically I just want to understand what that is and how I can fix it. I'm convinced it is linked to the exists() method in the security rules but I really can't put my finger on it.
Any advice, any suggestions, any hacks, all gratefully received!
Cheers all