I read many posts about this but didn’t find a proper suggested, official way to secure the votes count.
How do we secure;
- FieldValue.increment(1) so that malicious users cannot increment by 5,6 etc?
- If we check for userID’s (for ex; postID/likes/userIDs) How certain it is to check if it does not exist?
- Could you please show the suggested, right way of creating a basic user likes/vote security structure example?
For Cloud Function suggestions; Is it really practical to run a Cloud Function for just one like or voting of any kind?
Thank you,
3
Answers
You can compare current value and new value in security rules as shown below:
From the documentation, the
request.resource
variable contains the future state of the document whileresource.data
is current values.This however does not prevent user from using
increment(1)
multiple times. You must store user’s UID somewhere to check that.You can use
exists()
function to check if user has already voted but you must ensure that the document is added at first place. User may increment the count but block thecreate
operator that adds their vote’s record allowing them to cast multiple votes.One workaround would be to just add the vote document only instead of incrementing the count but then you’ll have to read all the documents later to get total counts of votes or use Firestore triggers for Cloud Functions to keep the count updated in the background.
When using Cloud Functions, it is ensured that the count will be incremented as well as the user’s vote record is added and no one can reverse engineer the code.
You can perform all this from the client and using rules, no need for Cloud Functions.
!exists
andexistsAfter
Or you could use a Firebase Cloud Function to do the task for you.
These are server-side code (here, firebase), so no one could modify it.