-
-
Parent Home: paired children, this month's free wake-up usage, and one tap to send Wake Now or open a schedule.
-
Each child's alarm schedule and activity — recurring school-morning wake-ups plus past wake / no-response results.
-
Parent adds an alarm: days, time and sound, delivered full-screen to the child's phone via Firebase Cloud Messaging.
-
WakeKids Plus paywall, built with RevenueCat's native paywall UI — unlimited Wake Now sends and recurring weekly schedules.
-
App Icon
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-uifor a native paywall, aplusentitlement gating unlimited Wake Now sends and recurring weekly schedules against a free tier capped at 1 child / 3 wake-ups per month, and arevenueCatWebhookCloud Function that syncs entitlement state into our ownuserAccessdocuments so a wake-up can be authorized without calling RevenueCat on the hot path.
Challenges we ran into
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.
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.
RevenueCat webhooks can race with themselves.
TEMPORARY_ENTITLEMENT_GRANTevents 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
- alarmkit
- android
- app-check
- cloud-functions
- fcm
- firebase
- firestore
- google-sign-in
- i18next
- ios
- jest
- mmkv
- node.js
- play-integrity
- react-native
- react-native-purchases
- react-navigation
- revenuecat
- sentry
- sign-in-with-apple
- swift
- tanstack-query
- typescript
- vision-camera
Log in or sign up for Devpost to join the conversation.