IDC Hajj & Umrah Guide
A full-stack Islamic pilgrimage companion app giving pilgrims offline-first access to Hajj, Umrah, and Madina ritual guides.
The Challenge
The central engineering challenge was building a content-heavy pilgrimage app that remains fully usable in poor network conditions — Makkah and Madina during Hajj season are among the most network-congested environments on earth, with millions of simultaneous users straining cell towers. The app implements a stale-while-revalidate offline-first architecture: every Firestore collection is cached to AsyncStorage with configurable TTLs, the app renders cached data immediately on load, and silently revalidates in the background when connectivity returns. A second challenge was managing a live schema migration without downtime. Unifying separate Firestore collections per ritual type into a single typed rituals collection required a TypeScript migration script using Firebase Admin SDK and a dual-write strategy where the admin CMS writes to both legacy and new schema simultaneously. The admin CMS presented its own complexity: upload order conflicts had to be detected and resolved before any file upload begins, keeping the content ordering consistent across a distributed content team without any locking mechanism.
Architectural Decisions
Offline-first with stale-while-revalidate
A dedicated useFirestoreData hook implements a three-phase strategy: immediately serve from AsyncStorage cache, flag data as potentially stale, then fetch from Firestore and silently update. This means pilgrims see content instantly even with no signal.
Anonymous Firebase Auth as access gate
All users authenticate via Firebase Anonymous Auth on app start. This enables Firestore security rules without requiring user registration, which would create friction for pilgrims who just want ritual guidance.
Versioned Firestore schema with typed migration
Every document carries a schemaVersion field enforced at the Firestore rules layer. A TypeScript migration script using Firebase Admin SDK handled the transformation, allowing zero-downtime migration.
Dual-write bridge during CMS transition
The admin CMS writes ritual content to both the legacy collections and the new rituals collection simultaneously, using _legacyFolderId and _newSchemaId as cross-references. This bridges the schema transition period without data loss risk.
File-based routing with Expo Router
Dynamic routes are defined via Expo Router file-system convention, matching Next.js App Router semantics. This gives typed route parameters, enables deep-linking, and keeps navigation logic co-located with screen files.
NativeWind for cross-platform styling
NativeWind brings Tailwind CSS utility classes to React Native. This means the same mental model and class names work across the mobile app (NativeWind v4) and the web admin (Tailwind v4), significantly reducing context-switching.
Magnetometer-based Qibla compass
The Qibla direction finder uses expo-sensors to subscribe to the device magnetometer and computes the heading via Math.atan2(y, x). This works entirely on-device with no API call, which is critical when connectivity is poor.
Hijri calendar integration
Prayer times and date displays use moment-hijri alongside moment to show Islamic calendar dates natively. This is essential for the target audience — pilgrims track ritual timing by Hijri date, not Gregorian.