I use the following Cloud Function:
exports.likePost = functions.https.onCall(async (data, context) => {
// ...
const db = admin.database();
// check if post is already liked
const likeInteractionRef = db.ref(...);
const snapAlreadyLiked = await likeInteractionRef.once("value");
const alreadyLiked = snapAlreadyLiked.exists();
if (alreadyLiked) {
// remove the like
await likeInteractionRef.remove();
// decrease post's like count await
likeCountRef.set(admin.database.ServerValue.increment(-1));
} else {
// set as liked
await likeInteractionRef.set(true);
// decrease post's like count
await likeCountRef.set(admin.database.ServerValue.increment(1));
}
// return success
return { success: true };
});
There is one problem: It is not idempotent. If the function is called twice by the same user without delay, it will go to the same branch of the if-else-statement and the like-count will be incorrect after.
How can I fix this?