After testing out several ways to build custom Like buttons and up/down voting systems, I’ve discovered the fastest method.
What doest work
At first it might seem obvious to implement a workflow that adds +1 to a like button or upvote. However, this makes it hard to keep track if current user has already added a like or a vote, and makes it near impossible to then “unlike” the liked post.
Another method is to have a “likes” database. Then to retrieve the total likes or upvotes is to do a search for all the people that have liked a post. This, as you might expect, is very slow.
The fastest method
The fastest method that I’ve found is to add a data field inside a post type “list of users”. Every time a user clicks “like”, the user is added to that list. If the user clicks “like” again, you remove the user (with the conditional, only when: if this list contains current user, remove ). So retrieve total list simply do a list :count.
This has proven to be the fastest in terms of like - dislike dynamics, and vote up, vote down dyanmics.
If anyone else wants to chime in and add their method, would be delighted to hear.
Hope this helps!
Fully agreed with your proposed approach as optimal. I follow the same methodology.
The problem with your method is security: that means each and every user could read list of those who liked this “item”.
Obviously - if that fits to your security plan - not a problem at all.
Hmmm, never considered this. Is there a way to patch this up?
You can have two data fields
So you’d do your conditionals based on the LikesUsers, but for security reasons, you only allow Users to see LikesCount.
Hope that helps,
I see, update the likesCount (number) with each interaction (+1, -1). It’s an additional step to run, seems slower.
How does facebook does it? You can see the like count AND a list of users who liked it, and go to their profile etc…
Perhaps @petrucho or @Nocodify can explain why this would be a security risk?
To me it’s not necessarily a security risk.
Depends on the type of app you’re building though! For a social network, it seems fine.
Your storing User object and you have to have “READ” permission to List them and then count them.
And again: if your’re OK with that - there is no big problem.
I would definitely double check this with Bubble support.
Thanks for weighing in! This is an important factor. It seems security isn’t discussed nearly enough as it should in the forum. @Nocodify @petrucho do you guys have a privacy guide somewhere that you could post here to compliment the discussion?
It’s hard to advice security guidelines without knowing product itself.
The only I can advise is create a test user and add minimum access as possible (block everything) and then step by step trying to reach all system functionality and granulary grant access.
Hi @alejandrowunderlich ,
I’m trying to implement your solution (I’m a total noob) and the like part is working fine. However when I have a second workflow to take out my user again it always happens instantly after adding the user to the list. So I click on the heart icon, my user gets added, then the second event fires and the user gets deleted right away again. I tried to add this workflow on a second action, thinking it should work but obviously I’m wrong. Do you have a hint what I’m doing wrong here?
Hi and welcome to the community.
Updating on my original post, I’ve tested several approaches to do a proper like / unlike button that retains the ability to display a list of all who have liked it. With a large database of users (in the thousands), it’s not instant like in Facebook.
This is what I do:
The DB thing has a list of texts (likes) where you’ll store all the user’s unique ids that liked it.
Then two separate workflows linked to the action of clicking the like button.
One WF has a conditional that checks if the post’s list of unique ids doesn’t contain the current user’s unique id (for adding the like).
The second WF has a conditional that checks if the post’s list of unique ids contains the current user’s unique id (for removing the like).
On each WF simply change the thing’s list of likes by either “plus item” or “remove item” from the list of unique ids.
Honestly, I’m yet to figure out a scalable, super fast way to do a like button properly. Especially tricky if the number of likes scales up to the 100s. Perhaps someone more savy in this topic can enlighten us. I suggest you add a “pulse” animation or something before the step of adding or removing the unique id so the user at least has the feedback that they’ve clicked the like button.
Let me know if this makes sense!
Having lists of any type in any object forces Bubble to upload them to the browser for each entry of a list of that object.
This makes the app slower as the number of entries grows as time goes by.
To display the number of likes an object has in a performant way, it may be better to resort to using a number field that is updated as a like is added or subtracted. What the user sees is after all a number.
Thanks for your input. I’ve tried this approach too. The slow part isn’t displaying a :count from a list or just a number. The slow part is checking if the current user has already liked the thing or not as it requires a “search for”.
May I suggest creating an object called like with two text fields. One for the unique ID of the object being liked and one for the user who liked it.
Yes you would have to do a search but it may be faster than the alternative which is to have those objects with lists of texts slowing down the page.
You could do one search for all of the likes that contain the current user and have that hidden in a repeating group placed in a popup that you never open (call it “var likes”). And then condition the object’s like icon’s visibility to be visible when the hidden rg contains the object’s unique id. The search will be faster because this like object will have only two text fields and nothing else. It would be a “light” object.
Indirectly linked dB models are usually more scalable
could you share a design so I can see exactly how this is implemented? I am trying to add a feature like this as well, and need to be able to show all the users I’ve “liked” on another page in an RG.
The other issue with this method is scalability. If I were to have 10,000 likes in a list of users on a given post, and one more user wanted to like the post (such that it would make it 10,001 if they WERE ABLE to like the post), they would be unable to do so. The inability to interact with a website meant for interaction is very frustrating to users.