
Lessons from building a deal-aggregator app: expiring content is a harder cache problem than I expected
Native Android, Kotlin. The app aggregates time-limited free-game offers from a bunch of storefronts. Sounds like a simple list screen. The expiry semantics are what made it interesting.
A few things I got wrong first time:
Stale data is worse than no data here. A normal feed can be five minutes behind and nobody dies. In this app, a five-minute-stale card means someone taps through to an offer that just closed and concludes the app is broken. I ended up [describe your approach — server-side refresh cadence, TTL, invalidation on open].
Countdowns and lifecycle. Every card renders a live countdown. Naively that's one ticker per visible row and the list stutters. I moved to [single ticker driving state / whatever you did] and made sure it stops on onStop so it isn't burning cycles in the background.
Device clock lies. People's clocks are wrong, sometimes by hours, and timezones make "2 days left" ambiguous. Everything is stored as UTC instants and I [compute offsets against a server timestamp / etc.] rather than trusting local time.
Sorting by expiry means the list reorders under the user's thumb. Genuinely annoying if you don't handle it. I [describe: stable keys, no resort while scrolling, etc.].
Offline. The list has to render from cache the moment it opens, then reconcile. Room + [your setup].
Happy to go deeper on any of it. The app is GamesBolt if you want to see the result: https://play.google.com/store/apps/details?id=com.auragames.gamesbolt
If anyone's solved the "list that reorders itself while you're reading it" problem more elegantly, I'd like to hear it.