Scalable Favourites System

I am trying to figure out the best way to make a scalable favourites/likes system. Currently I store favourites on a list (which is stored on the user). I limit this to 60 items for performance reasons. However I do not like having this hard limit and would rather allow it to be limitless for future-proofing and scalability.

I have experimented using the database method as recommended elsewhere in the forum. By this I mean I created a new ‘favourites’ table which then stores the song and the user that favourited it. This would be ok but leads to two new issues: 1) In order for the ‘heart’ icons to reflect whether or not the item has been favourited it has to have a ‘search for’ condition on every single cell in the repeating group. This is surely not performant or WU friendly. Furthermore, 2) there is a noticeable delay when storing & retrieving the favourites this way.

To get around the sluggishness issue I can use a state: ie do a search for the relevant favourites and push them into a list state on page load. The icon conditions would then check against that list (rather than doing a db search). This is much more ‘snappy’ from user perspective and works well. The downside of this however, is that it then causes the very issue that we wanted to avoid in the first place: loading big lists. For example, if user favourited 30,000 items it would require to load in 30,000 items into the state on page load! argh

So as it stands i am not sure what the best method is, and would love to hear some expert opinion on if there is a perfect solution for this… snappy user experience but with no limit on number of favourites allowed…

Many thanks

It depends on how you show the User the “Items” that can be favorited. Let’s say these are Songs…

You don’t have to store all the Favorites in one single list.

For Example:
You can use another object that filters by the Current User + The Artist then lists all the songs liked and you will likely never reach thousands of items in a list. Break it down further based on your scenario.

*Artist-Favorites

  • User (single)
  • Artist (single)
  • favorited_songs (list)

If this is an Instagram App where you want to show the amount of likes of an Item, then you take a different approach.

Storing the data in a manner that the User can arrive to it in the same way they arrive to the assets on screen usually helps.

Don’t Forget: You may need to break a few rules :wink:

IMO this is the only scalable way:

Also every time someone “likes” you can update a number field on the song with the total number. So you can easily sort songs by most liked

3 Likes

I wanted to mention that I use this technique, and to make it smoother I use privacy rules so a user can only see their own likes. This means I’m not searching that large of a list, and I never need to constrain by User - any data pulled is ONLY Current User thanks to those privacy rules.

5 Likes

Thanks for the replies so far. I maybe being a bit dumb but I can not find anything in the above which makes me think “ah ha! so that’s what i need to do!” I will try to address each suggestion and hopefully someone can help shed some more light on it.

These are indeed songs :slight_smile: It’s literally just one big list of songs, of various creators, and each one has a heart icon next to it. The heart indicates whether it is a favourite or not. Please see this video and image for further clarification how it behaves (which is currently a nice snappy user experience, which is great - but limited to 60 favourites, which is not so great).

Video: likes.mov - pCloud

The condition:

With the video in mind, does your suggestion still make sense ? I am confused when you speak about not saving the items in a single list as I can not envision in the slightest how that could work in this case.

Yes this is the database method I have tested, and it works ok but it doesn’t solve the ‘sluggish’ user-experience issue. It can take SECONDS for the icon to reflect the change. No good. The goal would be to have the database writes happen in this way, yet reflected instantly to the user visually. This is why I am using a ‘state’ - but populating that state (without it becoming a long list) becomes the future potential bottle-neck and challenge to solve here.

If i set privacy rules this way, wouldn’t that stop other users from viewing other users favourites? This is a feature for me as I want the song creators to be able to view who has favourited their songs.

Also what does your icon conditional look like? Are you doing a ‘search’ on every single icon. Or are you storing the list in a state? If so, you would still run into the issue of potentially massive state-lists. ?

On a tangent thought, can anyone confirm if we need a separate user field when we already have ‘created by’? would ‘created by’ be sufficient? (it would half the number of database writes if so).

Thank you for any further help given.

I think you should preload the liked list in small batches as well. If you know which songs are displayed in the page currently (maybe through a paging system or whatever), you can limit the liked list to those items only.

2 Likes

There’s some great advice in this thread! I think the most straightforward approach for you is @tylerboodman 's method using the Privacy Rule setup. Here are a few key points to consider:

  1. Privacy Rule for Users: This will speed up your results because users can only search for items they have access to.

  2. For Creators:

• Every time you create a new “User_Favorite” item, update the song’s favorite count. This way, users can see the number of likes instantly without loading the entire user list. You can also easily sort based on the number. This will come in handy for analytics and other features later.

• When creators want to see a list of users who liked their songs, consider these options:

Option 1: Store a “short list” of users (e.g., the first 5 or last 5) who liked the song. This allows you to display a message like: “John, Jane, Luke, Mike + 567 others liked this song.”

Option 2: When the creator clicks “see all,” perform the search then. It’s acceptable for creators to wait a few seconds to get the results. Introduce the records in batches (e.g., 50 at a time). The reality is, if 5,000 people liked your song, you probably don’t need to see every user’s name. You just want to know that 5,000 people liked it.

As for the favorites search and custom states, I don’t recommend this approach. The condition should be:

“Do a search for ‘Favorite_Item’ where Song = (current cell’s song) and User = Current User & then use the operator First Item is not Empty OR use the operator Count > 0

2 Likes

This sounds like a good idea! So rather than one big initial search that pushes ALL the likes into one state upon the page-load, I will just search for the songs that are being displayed on the current page of the repeating group and compare to those. (items 1>17 for example). Thank you, really like this idea and could well be the solution required!

Thank you Hi.luisacosta - some really good ideas here. Will implement some of these for sure.

Out of interest why wouldn’t you suggest this approach? Your approach would lead to 17 separate searches (one for each item on the page), which would increase WUs. Furthermore it would not address the ‘sluggish gui’ issue i am trying to avoid, which comparing to ‘states’ takes care of nicely.

Does anyone have any thoughts on this? Would creating a ‘user’ entry on the favourites table be redundant? (because that user would already be the “created by” entry). Please confirm.

If you are 100% sure that a like will only be created by the current user, you can use created by for sure. I usually approach created by with some suspicion though.

2 Likes