Ignyr — Keep the Fire Burning 🔥
Inspiration
Habit tracking apps are everywhere, but most of them are either too complex or locked behind expensive paywalls that don't make sense for someone just starting out. I wanted to build something dead simple: you pick a habit, you show up every day, and the streak does the motivating for you. The idea of a fire that goes out if you miss a day felt like the right metaphor — urgent enough to keep you honest, satisfying enough to keep you coming back.
Shipathon was the perfect forcing function. A real deadline, a real product.
How I Built It
Ignyr is a Flutter app backed by Firebase and monetized entirely through RevenueCat.
- Auth — Firebase Auth with Google Sign-In and email/password
- Data — Firestore stores streaks and daily completions per user, with cascading deletes on account removal
- Notifications —
flutter_local_notifications+firebase_messagingfor smart daily reminders, rescheduled on reboot - Monetization — RevenueCat with two subscriptions: monthly ($2) and yearly ($20), tied to an
ignyr_proentitlement. Offerings configured through the RevenueCat dashboard and fetched at runtime — no hardcoded prices in the app
The free tier allows 3 streaks. Premium unlocks unlimited streaks, detailed statistics, custom reminder scheduling, and a leaderboard badge.
What I Learned
Integrating RevenueCat was the smoothest part of the whole build. Configuring entitlements and offerings in the dashboard, then calling Purchases.getOfferings() in the app, meant I never had to touch receipt validation or server-side logic. The SDK handled everything.
What I didn't expect to learn: how many moving parts exist between "subscriptions configured" and "user can actually buy." Google Play service account credentials, Play Billing Library version requirements, linking GCP projects — none of that is in the RevenueCat docs because it's a Google problem. But once it clicked, it clicked.
Challenges
Google Play Billing setup was the biggest friction point. The app initially bundled Play Billing Library 7.x, which Google rejected. Upgrading purchases_flutter to ^10.0.0 resolved it, but required migrating to the new PurchaseParams.package() API.
Auth race condition — on a fresh install, the Firebase Auth stream fires before the splash screen finishes, causing users to land on the dashboard before they've logged in. Fixed by using FirebaseAuth.instance.currentUser (synchronous) at splash rather than listening to the auth stream, and adding an _initialEmitSeen flag to skip the stream's first emission.
Service account key creation was blocked by a Google Cloud organization policy (iam.disableServiceAccountKeyCreation), which prevented RevenueCat from getting the credentials it needed to validate purchases. Took longer to debug than it should have.
What's Next
- iOS release
- Leaderboard between friends
- Widget for the home screen — your streak count, one glance away
Log in or sign up for Devpost to join the conversation.