Role
UX Researcher · Systems Designer · Software & Embedded Prototyper
Stack
React Native · Firebase · React · ESP32 · GSM/GPRS · Cloud Functions
Team
Fatima Mamu, Valentina Arongo
UMMA NA is a full-stack emergency transport system designed to help pregnant women reach the right facility during life-threatening obstetric emergencies in rural Nigeria. It enables trained community health workers (CHIPS agents) to trigger emergency requests, tracks volunteer ETS drivers via custom-built GPS devices, and intelligently matches patients to hospitals based on capability and proximity—not just distance.
The system was designed to operate in low-infrastructure environments, where smartphones, data, and reliable health access cannot be assumed. By bridging medical, logistical, and infrastructural gaps in a single coordinated flow, UMMA NA addresses one of the world's most critical maternal health challenges.
Nigeria accounts for nearly 30% of global maternal mortality. In rural areas, many women die from preventable pregnancy complications simply because they cannot reach the right hospital in time.
Through extensive field research in rural Nigerian communities, we uncovered critical insights that shaped our system design:
CHIPS agents are literate, trained, and already use tools like WhatsApp, making a mobile app both viable and familiar.
ETS drivers often lack smartphones and have lower literacy levels, requiring a hands-off location tracking solution.
Critically: Women are frequently taken to the closest facility, not the most capable. If the first facility cannot handle the emergency, delays arranging second transport often lead to preventable death.
These insights shaped a system that bridges medical, logistical, and infrastructural gaps in a single flow, from home to hospital.
This journey map reflects the real-world flow across three critical stages of care: Seeking, Reaching, and Receiving, with parallel actions by CHIPS agents, drivers, hospitals, and the UMMA NA system.
Visual journey map showing parallel actions across seeking, reaching, and receiving care stages
CHIPS agent identifies emergency symptoms during home visit and triggers request through mobile app
System auto-matches nearest available ETS driver via GPS tracker and calculates optimal hospital route
Patient arrives at facility best equipped to handle her specific condition, increasing survival chances
The system includes four tightly connected components working in harmony to coordinate emergency response:
(React Native)
Allows agents to request help based on symptoms
(ESP32 + GSM)
Transmits live location from non-smartphone users
(Firebase + Cloud Functions)
Calculates best hospital match and routes request
(React + Firebase)
Displays requests, drivers, facilities, and analytics
Architecture diagram showing data flow between system components
Built in React Native using Expo, enabling emergency requests to be submitted quickly and reliably.
Since many ETS drivers do not own smartphones or may not interact with apps reliably, I designed a low-cost GPS device assigned to each driver.
Custom-built GPS tracker device for ETS drivers
The dashboard is used by hospitals and coordinators to monitor, assign, and respond to requests.
Smart algorithms match patients to hospitals based on condition-specific requirements, not just proximity. The system evaluates multiple factors simultaneously to optimize patient outcomes.
Each hospital is profiled with 18+ capability flags (surgery, blood bank, monitoring equipment) matched against condition requirements
Multi-factor time calculations including driver location, vehicle speed, and condition-specific time windows
Real-time composite scoring with weighted factors, exponential time penalties, and context-aware adjustments
See Technical Implementation section below for detailed algorithm breakdown and code samples
UMMA NA's technical architecture demonstrates sophisticated full-stack engineering, combining real-time systems, complex algorithms, and production-ready infrastructure. Here's how the core systems work under the hood.
The heart of UMMA NA is a multi-tiered scoring algorithm that routes patients to the most appropriate facility based on condition severity, hospital capabilities, and travel time—not just proximity.
// Core matching algorithm from backend/index.js const calculateHospitalScore = (hospital, condition, driverLocation, pickupLocation) => { const capabilities = hospital.capabilities || {}; const conditionRequirements = CAPABILITY_REQUIREMENTS.find(c => c.condition === condition); // Capability scoring with weighted requirements let capabilityScore = 0; const { ideal, acceptable, timeWindow } = conditionRequirements; const meetsIdeal = ideal.every(capability => capabilities[capability]); const meetsAcceptable = acceptable.every(capability => capabilities[capability]); if (meetsIdeal) capabilityScore = 100; else if (meetsAcceptable) capabilityScore = 75; else return null; // Hospital cannot handle this condition // Time-based scoring with exponential penalty const distanceToHospital = haversineDistance(pickupLocation.lat, pickupLocation.lng, hospital.lat, hospital.lng); const totalTripTime = (driverToPickupTime + distanceToHospital / vehicleSpeed) * 60; let timeScore = 100; if (totalTripTime > timeWindow) { timeScore = Math.max(40, 100 - Math.pow((totalTripTime - timeWindow) / 30, 1.5)); } return { hospitalId: hospital.id, score: capabilityScore * (timeScore / 100), totalTripTime, meetsIdeal, reasoning: `${meetsIdeal ? 'Ideal' : 'Acceptable'} care, ${totalTripTime.toFixed(0)}min trip` }; };
Since CHIPS agents aren't trained to diagnose, I built an expert system that maps symptom combinations to likely conditions using weighted scoring and contextual logic.
// From utils/conditionIdentifier.js - ML-inspired classification function identifyCondition(symptoms = [], patientContext = {}) { const { is_pregnant = false, is_postpartum = false, is_urgent = false } = patientContext; // Initialize scoring matrix for all possible conditions const conditionScores = {}; CONDITION_MAPPINGS.forEach(mapping => { conditionScores[mapping.condition] = { score: 0, requiredMatches: 0, optionalMatches: 0, confidence: 0 }; }); // Score each condition based on symptom matches CONDITION_MAPPINGS.forEach(condition => { // Required symptoms must ALL be present (100 point base) if (condition.requiredSymptoms && condition.requiredSymptoms.length > 0) { const matches = condition.requiredSymptoms.filter(s => symptoms.includes(s)).length; const percentage = matches / condition.requiredSymptoms.length; if (percentage === 1.0) { conditionScores[condition.condition].score += 100; } else { conditionScores[condition.condition].score += 50 * percentage; } } // Optional symptoms add incremental confidence (10 points each) if (condition.optionalSymptoms) { condition.optionalSymptoms.forEach(symptom => { if (symptoms.includes(symptom)) { conditionScores[condition.condition].score += 10; } }); } }); // Apply contextual ML-style feature weighting if (is_postpartum) { conditionScores.postpartum_hemorrhage.score *= 1.5; // Boost relevant conditions conditionScores.preterm_labor.score = 0; // Eliminate impossible conditions } // Find highest scoring condition with confidence threshold const bestMatch = Object.entries(conditionScores) .reduce((best, [condition, data]) => data.score > best.score ? { condition, score: data.score } : best, { condition: "unknown", score: 0 }); return { condition: bestMatch.condition, confidence: Math.min(bestMatch.score / 150, 0.95), requiresHighestCare: bestMatch.score < 105 && symptoms.length >= 3 }; }
For emergency cases, UMMA NA uses a two-tier selection process: first identifying candidate drivers, then requesting fresh GPS locations via push notifications for optimal matching.
// From backend/index.js - Advanced driver selection algorithm app.post('/request-ride', async (req, res) => { const { chipsAgentId, symptoms, pickupLat, pickupLng } = req.body; const complicationType = identifyCondition(symptoms); const isEmergent = ['PPH', 'eclampsia', 'obstructed_labor'].includes(complicationType); // TIER 1: Initial candidate selection (up to 7 closest drivers) const driversSnapshot = await db.collection('etsDrivers').where('isAvailable', '==', true).get(); const initialCandidates = driversSnapshot.docs .map(doc => { const driver = { id: doc.id, ...doc.data() }; const location = driver.isLocationFresh ? driver.lastKnownLocation : driver.fallbackLocation; const distance = haversineDistance(location.lat, location.lng, pickupLat, pickupLng); return { ...driver, distanceToPickup: distance, speed: speedMap[driver.vehicleType] }; }) .filter(d => vehicleRules.allowed.includes(d.vehicleType)) .sort((a, b) => a.distanceToPickup - b.distanceToPickup) .slice(0, 7); // TIER 2: Request fresh locations for emergent cases if (isEmergent && initialCandidates.length > 0) { const locationRequests = initialCandidates .filter(driver => driver.pushToken && !driver.isLocationFresh) .map(driver => admin.messaging().send({ token: driver.pushToken, data: { type: 'LOCATION_UPDATE', immediate: 'true' }, android: { priority: 'high' }, apns: { headers: { 'apns-priority': '10' } } }) ); await Promise.all(locationRequests); await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for fresh locations } // FINAL SELECTION: Re-score with fresh data const finalSelection = refreshedCandidates.sort((a, b) => { if (isEmergent) { const timeA = a.distanceToPickup / a.speed * 60; const timeB = b.distanceToPickup / b.speed * 60; return timeA - timeB; // Minimize response time for emergencies } return a.vehicle.isPreferable && !b.vehicle.isPreferable ? -1 : 1; // Prefer better vehicles }); // Create ride request with top driver + notify all candidates const selectedDriver = finalSelection[0]; // ... rest of implementation });
The system uses Firestore with carefully designed collections, indexes, and real-time subscriptions to handle concurrent requests while maintaining data consistency.
// Complex query with error handling and retry logic const getDriverActiveRide = async (driverId) => { const activeStatuses = ['pending', 'accepted', 'en_route_to_pickup', 'arrived_at_pickup']; try { const rideSnapshot = await db.collection('rideRequests') .where('driverAssigned.id', '==', driverId) .where('status', 'in', activeStatuses) .orderBy('createdAt', 'desc') .limit(1) .get(); if (rideSnapshot.empty) return null; // Enhance with related data (CHIPS agent details) const rideData = rideSnapshot.docs[0].data(); const chipsAgent = await db.collection('chipsAgents').doc(rideData.chipsAgentId).get(); return { id: rideSnapshot.docs[0].id, ...rideData, chipsAgentDetails: chipsAgent.exists ? { name: `${chipsAgent.data().firstName} ${chipsAgent.data().lastName}`, phoneNumber: chipsAgent.data().phoneNumber } : null }; } catch (error) { console.error('Database query failed:', error); throw error; } };
Built with enterprise-level considerations for security, monitoring, error handling, and scalability.
Firebase Admin SDK with service account authentication, environment variable management, and input validation on all endpoints.
Comprehensive try-catch blocks, structured logging with context, and graceful failure handling for external service dependencies.
Request/response time tracking, database query optimization, and location freshness validation for optimal driver selection.
Push notification system for immediate driver updates, offline-to-online sync handling, and state management across mobile/web platforms.
Real-time subscriptions for live driver tracking, offline-first mobile support, and automatic scaling for rural deployments with unpredictable usage patterns. The document model maps naturally to emergency request workflows.
Balances response speed (immediate selection from cached locations) with accuracy (fresh GPS data for emergency cases). The 2-second timeout prevents delays while allowing location updates to arrive.
CHIPS agents lack medical training for diagnosis. The expert system approach with weighted symptom scoring provides consistent condition identification while remaining within agents' skill level.
UMMA NA was rigorously tested in real-world conditions across multiple rural healthcare facilities and communities in Nigeria.
PHCCs tested
Villages covered
Emergency simulations
Time to dispatch improved from ~2 hours → ~20 minutes with automated driver matching
Offline-to-online sync behavior confirmed in real-world low-signal conditions
GPS tracker location visible in dashboard within 10–15 seconds of request
LoRa-based fallback was explored for completely offline use, but was ultimately scrapped due to long-term scalability, cost, and device maintenance challenges. The final system relies on low-bandwidth GSM to minimize friction and ensure compatibility with existing infrastructure.
UMMA NA is a functioning, field-tested emergency coordination system designed for one of the world's most fragile care ecosystems.
Deep field studies & UX design
Mobile + web development
Custom hardware solutions
Grounded in local context
Designed to scale, to fail gracefully, and to save lives in the world's most challenging healthcare environments.
Ready for deployment across rural Nigeria with potential for adaptation to maternal care challenges globally.
End-to-end demonstration of UMMA NA emergency coordination system
UMMA NA demonstrates how thoughtful technology design can address critical healthcare challenges in resource-constrained environments.