UMMA NA Logo

UMMA NA

A Full-Stack Emergency Coordination System for Rural Maternal Care

Role

UX Researcher · Systems Designer · Software & Embedded Prototyper

Stack

React Native · Firebase · React · ESP32 · GSM/GPRS · Cloud Functions

Team

Fatima Mamu, Valentina Arongo

Overview

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.

Key Insights

Through extensive field research in rural Nigerian communities, we uncovered critical insights that shaped our system design:

📱

CHIPS agents are tech-ready

CHIPS agents are literate, trained, and already use tools like WhatsApp, making a mobile app both viable and familiar.

🚗

ETS drivers need hands-off solutions

ETS drivers often lack smartphones and have lower literacy levels, requiring a hands-off location tracking solution.

🏥

Distance ≠ Best care

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.

System Journey

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.

UMMA NA System Journey Map

Visual journey map showing parallel actions across seeking, reaching, and receiving care stages

1. Seeking Care

CHIPS agent identifies emergency symptoms during home visit and triggers request through mobile app

2. Reaching Care

System auto-matches nearest available ETS driver via GPS tracker and calculates optimal hospital route

3. Receiving Care

Patient arrives at facility best equipped to handle her specific condition, increasing survival chances

System Architecture

The system includes four tightly connected components working in harmony to coordinate emergency response:

CHIPS App

(React Native)

Allows agents to request help based on symptoms

Driver GPS Tracker

(ESP32 + GSM)

Transmits live location from non-smartphone users

Backend Engine

(Firebase + Cloud Functions)

Calculates best hospital match and routes request

Admin Dashboard

(React + Firebase)

Displays requests, drivers, facilities, and analytics

UMMA NA System Architecture

Architecture diagram showing data flow between system components

System Components

CHIPS Agent App (React Native)

Built in React Native using Expo, enabling emergency requests to be submitted quickly and reliably.

Features:

  • Symptom-based flow: Agents select from visual symptom prompts (no diagnosis needed)
  • Auto-match logic: Sends request to the most capable reachable facility, not just the nearest
  • Localization: Hausa translation and visual icon support
  • Offline-first: Works in low-connectivity environments with sync when available
CHIPS Agent Mobile App Screens

ETS Driver Tracker (ESP32 + GSM/GPRS)

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.

Technical Specifications:

  • Microcontroller: ESP32
  • Connectivity: GSM/GPRS module, sends HTTPS requests to Firebase
  • Power: Rechargeable battery, multiple days runtime
  • Logic: Activated only when ride is assigned

Key Benefits:

  • Hands-free: Driver does nothing; system runs silently
  • Real-time tracking: Live location updates to dashboard
  • Low-cost: Affordable at scale for rural deployment
  • Reliable: Works where smartphones fail
ETS Driver GPS Tracker Device

Custom-built GPS tracker device for ETS drivers

Admin Dashboard (React + Firebase)

The dashboard is used by hospitals and coordinators to monitor, assign, and respond to requests.

Features:

  • Real-time view: All incoming requests with live status updates
  • Live tracking: ETS drivers displayed on interactive map
  • Facility database: Hospital readiness tags (hasBlood, hasSurgery, hasOxygen)
  • Smart matching: Cloud Functions compute facility scores dynamically
Admin Dashboard Interface

Intelligent Patient-Facility Routing

Smart algorithms match patients to hospitals based on condition-specific requirements, not just proximity. The system evaluates multiple factors simultaneously to optimize patient outcomes.

🏥 Capability Matching

Each hospital is profiled with 18+ capability flags (surgery, blood bank, monitoring equipment) matched against condition requirements

⏱️ Time Optimization

Multi-factor time calculations including driver location, vehicle speed, and condition-specific time windows

📊 Dynamic Scoring

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

Technical Implementation

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.

Intelligent Hospital Matching Engine

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`
  };
};

Symptom-Based Condition Classification

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
  };
}

Real-Time Driver Selection & Location Updates

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
});

Scalable Database Architecture

The system uses Firestore with carefully designed collections, indexes, and real-time subscriptions to handle concurrent requests while maintaining data consistency.

Collections & Indexing

  • Composite Indexes: status + createdAt for ride queries
  • GeoQueries: Location-based driver filtering
  • Real-time Listeners: Live ride status updates
  • Subcollections: Driver location history for analytics

Performance Optimizations

  • Batch Operations: Multi-driver notifications
  • Caching Strategy: Hospital capability lookup
  • Connection Pooling: Firebase Admin SDK
  • Query Limits: Pagination for large datasets
// 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;
  }
};

Production-Ready Infrastructure

Built with enterprise-level considerations for security, monitoring, error handling, and scalability.

🔐 Security & Authentication

Firebase Admin SDK with service account authentication, environment variable management, and input validation on all endpoints.

📊 Error Handling & Logging

Comprehensive try-catch blocks, structured logging with context, and graceful failure handling for external service dependencies.

⚡ Performance Monitoring

Request/response time tracking, database query optimization, and location freshness validation for optimal driver selection.

🔄 Real-Time Synchronization

Push notification system for immediate driver updates, offline-to-online sync handling, and state management across mobile/web platforms.

Key Engineering Decisions

Why Firestore over SQL?

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.

Two-Tier Driver Selection Strategy

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.

Symptom-Based vs. Diagnosis-Based Logic

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.

Field Testing & Results

UMMA NA was rigorously tested in real-world conditions across multiple rural healthcare facilities and communities in Nigeria.

3

PHCCs tested

14

Villages covered

50+

Emergency simulations

Key Results

⚡ Response Time

Time to dispatch improved from ~2 hours → ~20 minutes with automated driver matching

📶 Connectivity

Offline-to-online sync behavior confirmed in real-world low-signal conditions

📍 GPS Tracking

GPS tracker location visible in dashboard within 10–15 seconds of request

System Decisions

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.

Next Steps

  • Move GPS key tracker from perfboard to custom PCB
  • Add secure authentication + encryption to payloads
  • Expand hospital readiness data with real-time facility check-ins
  • Create analytics dashboard for health officials to monitor trends and response times

Impact & Next Steps

UMMA NA is a functioning, field-tested emergency coordination system designed for one of the world's most fragile care ecosystems.

What UMMA NA Uniquely Combines

🔍

Human-Centered Research

Deep field studies & UX design

💻

Full-Stack Engineering

Mobile + web development

Embedded Prototyping

Custom hardware solutions

🌍

Systems Thinking

Grounded in local context

Design Philosophy

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.

Full System Demo

End-to-end demonstration of UMMA NA emergency coordination system

Ready for Real-World Impact

UMMA NA demonstrates how thoughtful technology design can address critical healthcare challenges in resource-constrained environments.

View Technical Documentation Contact for Collaboration