Hi, I’ll try and keep this as short as possible.
I’m working on a social app and im currently working on the functionality which allows users to ‘LIke’ or ‘Unlike’ a post.
I’ve implemented this as a cloud function on Firebase, shown here…
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
/* this cloud function is used to update the likes on a post
- it receives three parameters in the post body
- and will update those respective fields in the post document (e.g number of likes)
*/
export const updateLikesCount = functions.https.onRequest((request, response) => {
let body: any;
if(typeof(request.body) == "string")
{
body = JSON.parse(request.body)
}
else
{
body = request.body;
}
console.log(request.body);
const postId = JSON.parse(request.body).postId;
const userId = JSON.parse(request.body).userId;
const action = JSON.parse(request.body).action; // 'like' or 'unlike'
// from this data object we can get the value of all the fields in the document
admin.firestore().collection("posts").doc(postId).get().then((data) => {
// if likes counts = 0, then assume there are no likes
let likesCount = data.data().likesCount || 0;
// likewise if there are no likes, then assign an empty array
let likes = data.data().likes || [];
let updateData = {};
if(action == "like")
{
updateData["likesCount"] = ++likesCount;
updateData[`likes.${userId}`] = true;
}
else
{
updateData["likesCount"] = --likesCount;
updateData[`likes.${userId}`] = false;
}
admin.firestore().collection("posts").doc(postId).update(updateData).then(() => {
response.status(200).send("Done")
}).catch((err) => {
response.status(err.code).send(err.message);
})
}).catch((err) => {
response.status(err.code).send(err.message);
})
})
Also, here is the function in my code which calls this function…
// This function deals with liking or unliking a post
like(post)
{
// Remember, as we are firing a cloud function we need a JSON object to send to it
// This object creates that JSON object to be sent to the cloud function for evaluation
let body =
{
postId: post.id,
userId: firebase.auth().currentUser.uid,
// does the post contain any likes, if so has the current user liked it already, if so then assign to unlike
action: post.data().likes && post.data().likes[firebase.auth().currentUser.uid] == true ? "unlike" : "like"
}
let toast = this.toastCtrl.create({
message: "Updating like... please wait"
});
toast.present();
// calling our cloud function, and passing in the object of data
this.http.post("https://us-central1-feedlyapp-4109f.cloudfunctions.net/updateLikesCount", JSON.stringify(body), {
responseType: "text"
}).subscribe((data) => {
console.log(data)
toast.setMessage("Like updated!");
setTimeout(() => {
toast.dismiss();
}, 3000)
}, (error) => {
toast.setMessage("An error has occurred. Please try again later.")
setTimeout(() => {
toast.dismiss();
}, 3000)
console.log(error)
})
}
Basically the ‘action’ is sent as a JSON object to the cloud function to be evaluated. If the user has already liked the post, then the action is ‘Unlike’, otherwise it should be ‘Like’.
However, for some reason every time the user clicks on the like button, the toast message saying “An error has occurred. Please try again later” appears… even though the likes/unlikes are updated in my firebase database. I do not understand what is going on, or what the error message means. Please Help! Thanks.
Also, here is the error message… both on the device and in the console.