Skip to the content.

πŸš€ Quick Start: Background Location for Driver App

Problem Solved

βœ… Socket stays connected when driver opens Google Maps
βœ… Location updates continue in background
βœ… Users see real-time driver location even when driver navigates in Google Maps


Mobile App Changes (3 Steps)

Step 1: Install Package

React Native:

npm install react-native-background-geolocation

Flutter:

# pubspec.yaml
background_locator_2: ^2.0.5

Step 2: Configure Permissions

Android - AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

iOS - Info.plist:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location to track trips in background</string>

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>

Step 3: Implement Background Service

React Native:

import BackgroundGeolocation from 'react-native-background-geolocation';
import io from 'socket.io-client';

// Initialize socket (same as before)
const socket = io('http://your-server.com:6065/location', {
  auth: { token: driverToken },
  transports: ['websocket'],
  reconnection: true,
  reconnectionAttempts: Infinity,
});

// Start background tracking when trip starts
BackgroundGeolocation.ready({
  desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
  distanceFilter: 10,
  stopOnTerminate: false,  // ⭐ Keep running after app closed
  startOnBoot: true,
  foregroundService: true, // ⭐ CRITICAL for Android
  notification: {
    title: 'Trip in Progress',
    text: 'Tracking your location',
  },
}).then(() => {
  BackgroundGeolocation.start();
});

// Listen to location updates
BackgroundGeolocation.onLocation((location) => {
  // Send to server (works in background!)
  socket.emit('update_location', {
    driverId: driverId,
    location: [location.coords.longitude, location.coords.latitude],
    speed: location.coords.speed || 0,
    accuracy: location.coords.accuracy,
    heading: location.coords.heading,
  });
});

// When driver clicks "Navigate"
const openGoogleMaps = (userLat, userLng) => {
  const url = `https://www.google.com/maps/dir/?api=1&destination=${userLat},${userLng}`;
  Linking.openURL(url);
  // Background service continues automatically! βœ…
};

// Stop tracking when trip ends
const stopTracking = () => {
  BackgroundGeolocation.stop();
  socket.disconnect();
};

New Socket Events (Server Already Supports!)

1. App Going to Background

// Mobile: Notify server when app goes to background
socket.emit('app_background', {
  driverId: driverId,
  isBackground: true
});

// Server confirms
socket.on('background_mode_set', (data) => {
  console.log(data.message); // "Background mode active - location tracking continues"
});

2. Session Restoration (when app comes back)

// Mobile: Restore session when app comes to foreground
socket.emit('restore_session', {
  driverId: driverId
});

// Server sends back active trip info
socket.on('session_restored', (data) => {
  console.log(data.activeTrip); // Current trip details
  console.log(data.message); // "Session restored successfully"
});

Complete Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    DRIVER APP FLOW                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  1. Trip Starts                                             β”‚
β”‚     ↓                                                       β”‚
β”‚  2. Start Background Geolocation                           β”‚
β”‚     ↓                                                       β”‚
β”‚  3. Socket connects and sends location every 5s            β”‚
β”‚     ↓                                                       β”‚
β”‚  4. Driver clicks "Navigate to Pickup"                     β”‚
β”‚     ↓                                                       β”‚
β”‚  5. App emits: app_background(isBackground: true)          β”‚
β”‚     ↓                                                       β”‚
β”‚  6. Google Maps opens (app in background)                  β”‚
β”‚     ↓                                                       β”‚
β”‚  7. Background service continues sending location          β”‚
β”‚     ↓ (Socket stays connected!)                            β”‚
β”‚  8. User sees driver moving in real-time βœ…                 β”‚
β”‚     ↓                                                       β”‚
β”‚  9. Driver switches back to your app                       β”‚
β”‚     ↓                                                       β”‚
β”‚  10. App emits: restore_session(driverId)                  β”‚
β”‚     ↓                                                       β”‚
β”‚  11. Server sends back active trip details                 β”‚
β”‚     ↓                                                       β”‚
β”‚  12. App UI updates with current trip                      β”‚
β”‚     ↓                                                       β”‚
β”‚  13. Trip completes                                        β”‚
β”‚     ↓                                                       β”‚
β”‚  14. Stop background tracking                              β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Server Changes (Already Done! βœ…)

Your server now supports:

  1. Background Mode Detection
    • Server knows when app is in background
    • Logs: β€œDriver X app went to BACKGROUND”
  2. Session Restoration
    • Re-registers socket mapping
    • Returns active trip details
    • Seamless reconnection
  3. Continuous Location Updates
    • Works same in background and foreground
    • Uses intelligent batching under high load
    • Redis caching for fast queries

Testing

1. Test Background Mode

# Start trip in app
# Click "Navigate to Pickup"
# Check server logs:
βœ… "Driver 123 app went to BACKGROUND"
βœ… "πŸ“ Location updated for driver 123"
βœ… "Broadcasting to users tracking driver 123"

2. Test Session Restoration

# Switch back to app from Google Maps
# Check server logs:
βœ… "πŸ”„ Restoring session: Driver 123 reconnected"
βœ… "Session restored for driver 123"

3. Monitor Metrics

curl http://localhost:6065/api/system/metrics

# Check:
- activeConnections: Should stay constant
- updatesPerSecond: Should continue in background
- batchModeActive: true if >50 updates/sec

Key Points

  1. Foreground Service Required (Android)
    • Shows persistent notification
    • Prevents Android from killing the service
    • User knows tracking is active
  2. Always Location Permission (iOS)
    • User must grant β€œAlways” permission
    • Required for background tracking
    • Explained in permission dialog
  3. Socket Reconnection
    • Automatic reconnection enabled
    • Infinite attempts (critical for background)
    • Uses WebSocket transport only
  4. Battery Optimization
    • User must disable battery optimization for your app
    • Otherwise Android may kill background service
    • Show prompt in app to guide user

Common Issues & Solutions

Issue: Location stops after 5 minutes

Solution:

Issue: Socket disconnects in background

Solution:

Issue: Google Maps opens but location stops

Solution:


Battery Impact

Optimized Settings:

{
  distanceFilter: 20,        // Update every 20 meters (not every move)
  desiredAccuracy: MEDIUM,    // Don't need GPS accuracy for navigation
  stopTimeout: 5,             // Stop tracking if stationary for 5 min
  heartbeatInterval: 60,      // Reduce heartbeat frequency
}

Battery Usage: ~5-10% per hour (acceptable for trip duration)


User Experience

Before (Without Background Service)

Driver opens Google Maps
  ↓
Socket disconnects ❌
  ↓
Location updates stop ❌
  ↓
User sees driver frozen on map ❌
  ↓
Poor experience 😞

After (With Background Service)

Driver opens Google Maps
  ↓
Background service continues βœ…
  ↓
Socket stays connected βœ…
  ↓
Location updates every 5s βœ…
  ↓
User sees smooth real-time movement βœ…
  ↓
Uber-like experience! πŸŽ‰

Next Steps

  1. βœ… Server is ready (no changes needed!)
  2. πŸ“± Implement background service in mobile app
  3. πŸ§ͺ Test with real devices
  4. πŸ“Š Monitor metrics endpoint
  5. πŸš€ Deploy to production

Need Help?

Check these files:

Your backend is production-ready! Just add the mobile background service and you’re done. 🎯