AD
All projects
TaleCards icon
Mobile2026

TaleCards

Personalized daily bedtime stories that grow with your child

Play Store Sole engineer

TaleCards computes each child's age in days and serves an age-appropriate story every day, with a 3-day trial funneling into a RevenueCat subscription. Shipped through 14 release builds with four auth providers, Crashlytics, App Check and timezone-aware daily story notifications.

The Problem

Parents want stories matched to their child's exact developmental stage, and the content team needed to expand age coverage without shipping app updates.

The Solution

Stories live in Firestore buckets keyed by day-age; the active content window is remotely configurable, and a modulo-wrap fallback guarantees a story every single day regardless of catalog gaps. RevenueCat entitlement changes sync to Firestore in real time, flipping the paywall reactively.

Architecture

  • Flutter + GetX with feature-first modules and documented Firestore schema
  • Multi-kid profiles → age-in-days → story-bucket mapping with live-streamed remote config
  • Auth: email, Google, Apple (crypto nonce + secure-storage of Apple's one-shot profile data), phone OTP
  • RevenueCat customer-info listener → Firestore isPremium → reactive paywall stream
  • Timezone-aware daily local notifications with downloaded cover images

Challenges & How I Solved Them

Never leave a child without a story

If a day-age bucket is empty, a modulo-wrap fallback re-maps into covered ranges: content gaps degrade gracefully instead of breaking the daily ritual.

Apple Sign-In done right

Apple provides name/email exactly once; they're cached in secure storage with a nonce-verified flow so account recovery works forever after.

My Contributions

  • Entire product: app, Firestore schema, subscriptions, notifications, release pipeline

Impact

  • Live on the Play Store and App Store: 14 release builds shipped (v1.0.7)
  • Full trial→subscription funnel in production

Lessons Learned

Subscription apps are state machines: trial, entitlement, and content-window states must each have a single source of truth or the paywall lies to someone.

Tech Stack

FlutterGetXFirebaseFirestoreRevenueCatApp CheckCrashlytics