Building Streaks šŸ”„ - How?

Hi there,

I have a Habit App and I want to add streaks to my habits. Like Snapchat or like Duolingo. If the user completes the habit +1 on the streak. If he does not the streak goes to zero.

The problem is: checking the status of the streak.

Currently I am saving the ā€œcompletedā€ dates as a list of texts (date:formatted as 24/07/2023) to each habit.

I am not sure how I can find out how long the current streak went - and it becomes even more complicated as I have different intervals (Daily, Weekly, Monthly, Yearly, Custom: user selects weekdays)

Maybe a possibility would be to just check the streak on the frontend (so have nothing in the database)?

Would be more than thankful for any hints on how to achieve this…

PS: obviously also open to make changes to the db

Why are you doing that? If you want to do anything to do with dates, then use dates, not texts.

But you probably don’t need to store every date… just the first and last of the streak.

When a user completes a task, check if the current date is more than 1 day since the existing end date of the streak.

If it’s not, then set the current date as the new streak end date.

If it is, then set the current date as the new streak start date.

2 Likes

The app also contains a calendar and it comes in handy to check if the task should be displayed that day. I am storing every date so that the user can go back in the calendar to see when he did what (probably not even that important)

To save the start and end date is an idea.

What about other cycles (weekly and most of all Custom: where the user selects different days of the week)? They are saved in the database as numbers (for :extract day)

The app also contains a calendar and it comes in handy to check if the task should be displayed that day. I am storing every date so that the user can go back in the calendar to see when he did what (probably not even that important)

So just store the previous streaks somewhere (probably as a separate datatype would be best).

What about other cycles (weekly and most of all Custom: where the user selects different days of the week)? They are saved in the database as numbers (for :extract day)

It depends what you mean exactly, but the same concept should apply regardless of the timeframe.

What i mean is that there are habits, with custom cycles; e.g. Exercise every Monday, Wednesday, Friday.

—> After a user completes their first action, cancel, then reschedule an APi WF to reset the streak tomorrow at 23:59pm. This way, the user basically pushes back the ā€œresettingā€ of their streak as long as they keep working out every day.

that could probably be a neat solution…

Hey maintainer of Trophy here.

Unfortunately yes, streaks are hard :slight_smile:

We’ve found the best way of handling them is to use an event log where each action a user takes becomes an event. You then compute the streak based on the events. For example if there’s at least one event per day the streak is uninterrupted, but any gaps and you consider those as reset points.

This makes it easy to compute different intervals as well as you can aggregate the event log over daily, weekly or monthly timeframes and the data stays the same.

That said there are a few gotchas with any streak feature:

  • DIfferent time zones
  • Users changing time zones (going on holiday)
  • Different starting days of the week (most countries are Sunday, but some are Monday)

To make sure you don’t artificially miss users streaks you need to compute streaks relative to the users time zone in the last location that they logged in. Otherwise if they change country they could lose their streak despite actually having done something that day.

Plus if you wanted to do a Duolingo-style ā€˜streak freezes’ feature then this gets even more tricky :slight_smile:.

Another option would be to just let Trophy handle it all. You can use the Bubble API Connector to have Trophy collect events and just query streaks directly from Trophy with it taking care of all the tracking properly.

I’d imagine a streak is tied to the completion of something, such as logging the duration of fitness routine, or completed learning goal, both of which are already likely being saved to the DB, so for me, it makes the most sense to at that moment create a log of the completed task. Bubble already has built in created date, so use it, and you likely have categories of such activities, so add to log, then you have your data to calculate streaks.

As for all the potential what about, it’s the same thing, category plus created date field, use the date to calculate days in row, or every Monday etc etc