Implement an Upvote Feature like Product Hunt & Reddit

Headshot of Matt the Planet No Code Bubble Coach

Need 1 to 1 help?

Your no-code consultant & Bubble tutor.

Providing an upvote feature for user-generated content is a significant factor for encouraging engagement and building an active user-base.

This video will guide you on how to create and integrate an upvote feature for user generated content in to stimulate user involvement and increase app popularity.

Add a repeating group

We're going to start with this
, and it's just showing my content of data type search for posts. And if we have a look in data, you can see I've just got some dummy content created in posts. And if we preview the app, it just lists through using the repeating group my three posts. So if I want to upvote the content, how would I go about that? Well, I'm going to show you a number of different methods to do so. I'm going to start by adding in a group into the row here and give this a little bit of padding and add in an icon. We'll make this a column, make this an upvote. A little bit bigger. Okay, so let's do it one method. Let's go about this by just creating a counter.

Upvote - Make changes to a thing

So when this group is clicked, I'm going to start a
and say make changes to thing and the thing is going to be my post because that's where I'm going to keep a record of how many upvotes it's received and I'm going to create a new field and call this "votes" and make it numerical and then all I'm going to do is say current or either of these it doesn't really matter we'll go with this post "votes add one" let's preview that In fact, I've got no way of giving any visual feedback on it, so I'm going to add in some text here, make this the post so I can carry the data down my elementary. Give it there, so we've got a repeating group, we've got the cell. So this is now post a vote, get rid of the width, let's they center it. Right preview that.


So when you can see that it's now become a button because the browser is responding with the hand icon ready to click and if I click it I can upvote. And you can see that in data it's now got four upvotes. So this is very limiting because what if I want to restrict the user to only upvote once? Well, I need to approach it in a slightly different way. So let's clear this down to zero. That is just emptying.

Track whether a user has already upvoted

So I've got to come up with a way of tracking whether a user has voted on the post or not. Now, one way of doing that would be to save the post to the user. And basically the user has a field which lists out all the posts they've voted on, I just need to be able to construct some sort of conditional statement that would allow me to say this user has voted for this post and to not allow them to vote anymore. The way I'm going to go about it is to create a field on the post called voted_by_user and so say that's the type user and then that this is a list. And then I change my workflow instead of using that "votes" - in fact, I'll delete that so we don't get confused - the votes number field is now gone. I'll say when this group is clicked I'm going to "voted by user add current user" and I need to do one other change which is rather than looking at the the numerical count which I've deleted I'm going to say "voted by user count". So currently zero and if I click it, it's not going to allow me to add more than one.

How Bubble handles list fields - no duplicates

Now that is to do with how Bubble handles lists, it's not allowing me to add the person more than once. And we can check that out by going back into data. So part of what's going on here is the fact that even though I'm running the app as a non logged in user and Bubble is using a cookie to track the session in order to do limited behaviors associated with current user but it's not able to actually track that that user has taken that action so I'm now running it as a logged in user and let's try this one yeah okay and then if I go into here into the post I can see that voted by user is now creating a list of the user and it's not going to allow me to add duplicates, it's only going to allow unique entries in there, which works fairly well for upvoting. I'm going to show you one last thing on this which is what if we want the user to be able to remove the vote that they've cast. So we add in a conditional statement here and we say only when current sales post voted by user doesn't contain current user, so that's going to restrict them to only running it once anyway. And then I'm going to copy and paste this. In fact, the condition, if we're really optimizing it, should go on the workflow square rather than the first instance. So let's just go back to one. I like to call it code, so I'll make this green because it's doing a positive action and I'm going to copy and paste that and this is going to be my negative action. So when the current post voted by user does contain current user, I want to remove goes down to zero, goes back up to one, goes down to zero because when the current user already exists in that field it runs this workflow and it removes current users from the field and we can check that in data by refreshing it and we can see that voted by user is now empty.

Bubble workflow optimization

Now there may come a point when you want to optimize this a little bit and here's just a starter for optimizing, which is that let's say you have a thousand users in your app, do you really want to be counting hundreds of upvotes every time the page loads? So the way around that would be to add in another step here. In fact, we could use a custom event because we're going to do the same thing twice. So this will be count votes and of type post. So when the user adds themself as a voter, we will trigger a custom event, results of step one, and we'll add in, make changes to a thing, this post, and we'll add back in the numerical votes. This is the stop us from having to run the count for every single cell in our table every time the page loads. So we'll say posts, no it's not, it is going to be posts voted by user count. We can add the same here. Now if I go back I'm going to display the number based on the numerical field not the count field. You can see it works exactly the same way but it's more optimized.

Bubble database optimization

If you were to have hundreds of users in that voting field, you're displaying a static number rather than having to run the count every time. One last thing, you might notice that the field is empty and it's not actually showing a zero. There are two ways you could count this. One would be in text here to say "on current posts 'votes is 0, text is 0'. Okay, let's check that. Okay, what have I done wrong there? Oh, 'votes' is a number field. Okay, so that's one way of approaching it, but only if you've got you've done this first, and then actually if you've done this there's no need to have this conditional statement. So basically all you needed to do was in post say votes number is zero. And that's simply because Bubble treats an empty field at least with a number sort of like zero, at least when it comes to doing calculations like the plus one I demoed at the start, but it won't display it as zero as you just saw if the field is completely empty. By putting a default into your data types and onto your into your field here you're just saying that every time a post is created it is actually zero rather than it just being empty.