Inspiration

School mornings break every assumption a normal alarm app makes. The person who needs to wake up is a kid in another room who silenced their phone, or a teenager who turns their own alarm off and goes back to sleep. When I looked at existing "family alarm" apps (Wayk, and a couple of "social alarm" apps), none of them actually let a parent trigger an alarm on a different device from their own phone — they're same-device, locally-scheduled alarms with wake-up "missions" bolted on. That gap — instant, remote, guaranteed-to-ring wake-up control, initiated by a parent — is why WakeKids exists.

What it does

WakeKids is a remote alarm clock for families. A parent pairs with their child's phone once via QR code, then builds a recurring school-morning schedule or sends a one-off "Wake Now" from their own phone. It rings full screen on the child's device — even on silent, even locked, where OS/device permissions allow — and reports back whether the wake screen was acknowledged or not. It deliberately does one thing only: no location tracking, no content filtering, no message reading.

How we built it

  • Client: React Native 0.84 (Android + iOS), with a full-screen alarm UI and iOS AlarmKit-backed scheduled alarms.
  • Backend: Firebase — Firestore + Cloud Functions on Node 22, hosted in europe-west3 (Frankfurt) for GDPR, FCM for push delivery, App Check (Play Integrity / App Attest) on every endpoint, and a server-authorized backup alarm so the child's device can self-arm if the network drops between the parent's action and delivery.
  • Pairing & child privacy: the backend only mints a scoped child UID after the parent explicitly authorizes the pairing — no child data exists before that point, which matters given the real audience is roughly ages 6–12.
  • Monetization, on RevenueCat end to end: react-native-purchases + react-native-purchases-ui for a native paywall, a plus entitlement gating unlimited Wake Now sends and recurring weekly schedules against a free tier capped at 1 child / 3 wake-ups per month, and a revenueCatWebhook Cloud Function that syncs entitlement state into our own userAccess documents so a wake-up can be authorized without calling RevenueCat on the hot path.

Challenges we ran into

  1. Apple doesn't want third-party apps to have real alarm power. We applied for the Critical Alerts entitlement so Wake Now could ring even through Do Not Disturb or a force-quit app. Apple rejected it in writing: the API is reserved for medical/security/safety use. Competitive research confirmed no third-party iOS app has solved this — even Apple's own closest analog, Find My's "Play Sound," is a first-party OS capability with no public API. We treated that as an architectural ceiling, not a bug: scheduled alarms (which arm ahead of time) carry the reliability guarantee; Wake Now is explicitly best-effort on iOS, and documented as such.

  2. A strict version check took down pairing for days. A backend change bumped a parental-authorization version string and checked it with strict equality, with no backward-compatible range. Cloud Function deploys are instant; the matching app update had to clear App Store/Play Store review and actually reach devices, which takes days — so every parent still on the old build got hard-rejected until they updated. The real lesson was about deploy ordering: backend and client changes for the same feature can never be assumed to land atomically for a store-distributed app.

  3. RevenueCat webhooks can race with themselves. TEMPORARY_ENTITLEMENT_GRANT events don't carry full subscriber state, so we resolve them via the authoritative REST subscriber snapshot — but that fetch takes time, and a newer webhook can land before the older fetch resolves. We watermark the snapshot request before firing it so a stale in-flight response can never overwrite a newer webhook's write.

What we learned

  • A platform's "no" can be the most useful signal in the project — Apple's Critical Alerts rejection told us exactly where the real product boundary is, and let us design an honest, correctly-scoped feature instead of chasing an unsolvable guarantee.
  • For a store-distributed app, "backend deployed" and "client deployed" are two separate timelines, always — never ship a breaking contract change on one side without a compatibility window on the other.
  • RevenueCat removed an entire category of work we'd otherwise have built ourselves (cross-platform receipt validation, entitlement state, a native paywall). The part we still had to get right ourselves was the seam between RevenueCat's webhook and our own backend's idea of the truth — that's where both of our real bugs lived.

What's next

Finishing the App Store release surface (Apple annual-price resolution, signed TestFlight build), then closing out the RevenueCat webhook/offering setup on the Apple side to match what's already live and tested on Android.

Built With

Share this project:

Updates

Submission history