How to Build a Live Tracking App with React Native Background Geolocation

Creating a Live Tracking Application Using React Native Background Geolocation ðŸ—º️


React-native-background-geolocation is described as "the most sophisticated background location-tracking & geofencing module with battery-conscious motion-detection intelligence for iOS and Android." It delivers battery-efficient, intelligent geolocation by monitoring device movement using accelerometer, gyroscope, and magnetometer sensors.


Get Started.

First, you need to install the react-native-background-geolocation plugin:
npm install react-native-background-geolocation --save

Next, follow the plugin documentation to configure your Android and iOS projects.
You can find the official documentation here: Click Here

If you have configured it successfully, create the GeolocationService class so that we can easily use it in our screens.

import BackgroundGeolocation from 'react-native-background-geolocation';

class GeolocationService {
    private static locationCallback: ((location: any) => void) | null = null;

    static initialize(onLocation: (location: any) => void) {
        this.locationCallback = onLocation;
        this.setupEventListeners();
        this.configureTracking(10000);
    }

    private static setupEventListeners() {
        BackgroundGeolocation.onLocation(
            location => {
                if (this.locationCallback) {
                    this.locationCallback(location);
                }
            },
            error => {
                // console.log("[location] ERROR: ", error)
            }
        );

        BackgroundGeolocation.onProviderChange((event) => {
            switch (event.status) {
                case BackgroundGeolocation.AUTHORIZATION_STATUS_DENIED:
                    console.log("- Location authorization denied");
                    break;
                case BackgroundGeolocation.AUTHORIZATION_STATUS_ALWAYS:
                    console.log("- Location always granted");
                    break;
                case BackgroundGeolocation.AUTHORIZATION_STATUS_WHEN_IN_USE:
                    console.log("- Location WhenInUse granted");
                    break;
            }
        });
    }

    private static configureTracking(intervalTime: number) {
        BackgroundGeolocation.ready({
            geofenceModeHighAccuracy: true,
            autoSync: true,
            desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
            distanceFilter: 50,
            stopTimeout: 5,
            debug: false,
            logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
            stopOnTerminate: false,
            startOnBoot: true,
            disableElasticity: false,
            isMoving: true,
            enableHeadless: true,
            disableMotionActivityUpdates: false,
            forceReloadOnLocationChange: false,
            forceReloadOnMotionChange: false,
            forceReloadOnGeofence: false,
            locationUpdateInterval: intervalTime ?? 10000,
            minimumActivityRecognitionConfidence: 40,
            fastestLocationUpdateInterval: 1000,
            activityRecognitionInterval: intervalTime ?? 1000,
            backgroundPermissionRationale: {
                title: "Allow access to this device's location in the background?",
                message: "Please enable 'Allow all the time' permission",
                positiveAction: "Change to Allow all the time",
                negativeAction: "Skip for now"
            },
            notification: {
                title: "Your App Name",
                text: "<Your App Name> Background Tracking Activated",
                sticky: true,
                priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_HIGH
            },
            locationAuthorizationRequest: 'Always',
            locationAuthorizationAlert: {
                titleWhenNotEnabled: "Allow access to this device's location in the background?",
                titleWhenOff: "Allow access to this device's location in the background?",
                instructions: "Please enable 'Always' permission",
                cancelButton: "Cancel",
                settingsButton: "Settings"
            },
            pausesLocationUpdatesAutomatically: false,
        }, (state) => {
            if (!state.enabled) {
                BackgroundGeolocation.start(() => {
                    GeolocationService.upgradeToAlwaysAllow();
                });
            }
        });
    }

    static upgradeToAlwaysAllow() {
        BackgroundGeolocation.setConfig({
            locationAuthorizationRequest: 'Always'
        });
    }

    static async stop() {
        const state = await BackgroundGeolocation.getState();
        if (state.enabled) {
            BackgroundGeolocation.stop();
            BackgroundGeolocation.removeAllListeners();
        }
    }
}

export default GeolocationService;


This service provides background location tracking functionality with high accuracy and proper permission handling for iOS and Android.

Key Components of GeolocationService Class

1. Class Structure
import BackgroundGeolocation from 'react-native-background-geolocation';

class GeolocationService {
    private static locationCallback: ((location: any) => void) | null = null;
  • Uses a static class pattern for singleton behavior
  • Stores a callback function to handle location updates

2. Initialization Method
static initialize(onLocation: (location: any) => void) {
    this.locationCallback = onLocation;
    this.setupEventListeners();
    this.configureTracking(10000);
}
  • Sets up the location callback
  • Configures event listeners
  • Starts tracking with 10-second intervals

3. Event Listeners Setup
private static setupEventListeners() {
    BackgroundGeolocation.onLocation(
        location => {
            if (this.locationCallback) {
                this.locationCallback(location);
            }
        },
        error => {
            // console.log("[location] ERROR: ", error)
        }
    );

    BackgroundGeolocation.onProviderChange((event) => {
        switch (event.status) {
            case BackgroundGeolocation.AUTHORIZATION_STATUS_DENIED:
                console.log("- Location authorization denied");
                break;
            case BackgroundGeolocation.AUTHORIZATION_STATUS_ALWAYS:
                console.log("- Location always granted");
                break;
            case BackgroundGeolocation.AUTHORIZATION_STATUS_WHEN_IN_USE:
                console.log("- Location WhenInUse granted");
                break;
        }
    });
}
  • Location Updates: Handles incoming location data and passes it to the callback
  • Provider Changes: Monitors location permission status changes

4. Tracking Configuration
private static configureTracking(intervalTime: number) {
    BackgroundGeolocation.ready({
        geofenceModeHighAccuracy: true,
        autoSync: true,
        desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
        distanceFilter: 50,
        stopTimeout: 5,
        debug: false,
        logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
        stopOnTerminate: false,
        startOnBoot: true,
        disableElasticity: false,
        isMoving: true,
        enableHeadless: true,
        disableMotionActivityUpdates: false,
        forceReloadOnLocationChange: false,
        forceReloadOnMotionChange: false,
        forceReloadOnGeofence: false,
        locationUpdateInterval: intervalTime ?? 10000,
        minimumActivityRecognitionConfidence: 40,
        fastestLocationUpdateInterval: 1000,
        activityRecognitionInterval: intervalTime ?? 1000,
        backgroundPermissionRationale: {
            title: "Allow access to this device's location in the background?",
            message: "Please enable 'Allow all the time' permission",
            positiveAction: "Change to Allow all the time",
            negativeAction: "Skip for now"
        },
        notification: {
            title: "ONE APP",
            text: "Background Tracking Activated",
            sticky: true,
            priority: BackgroundGeolocation.NOTIFICATION_PRIORITY_HIGH
        },
        locationAuthorizationRequest: 'Always',
        locationAuthorizationAlert: {
            titleWhenNotEnabled: "Allow access to this device's location in the background?",
            titleWhenOff: "Allow access to this device's location in the background?",
            instructions: "Please enable 'Always' permission",
            cancelButton: "Cancel",
            settingsButton: "Settings"
        },
        pausesLocationUpdatesAutomatically: false, // [iOS only]
    }, (state) => {
        if (!state.enabled) {
            BackgroundGeolocation.start(() => {
                GeolocationService.upgradeToAlwaysAllow();
            });
        }
    });
}

Key Configuration Options:
  • High Accuracy: Uses GPS for precise location tracking
  • Distance Filter: Only updates when user moves 50+ meters
  • Background Operation: Continues tracking when app is closed
  • Auto-start: Restarts tracking when device reboots
  • Notifications: Shows persistent notification during tracking
  • Permission Handling: Requests "Always" location permission

5. Permission Upgrade
static upgradeToAlwaysAllow() {
    BackgroundGeolocation.setConfig({
        locationAuthorizationRequest: 'Always'
    });
}
  • Prompts user to upgrade from "When in Use" to "Always" permission (iOS)

6. Cleanup Method
static async stop() {
    const state = await BackgroundGeolocation.getState();
    if (state.enabled) {
        BackgroundGeolocation.stop();
        BackgroundGeolocation.removeAllListeners();
    }
}
  • Stops tracking and removes event listeners
  • Checks if tracking is active before stopping

GeolocationService Usage Guide

The GeolocationService is a background location tracking service that provides continuous location updates even when the app is in the background. Here's how to use it:

// Initialize the service with a callback function
GeolocationService.initialize((location) => {
    console.log('New location received:', location);
});

To continuously track a user’s location in real time, you can initialize a geolocation service that listens for movement and updates the user’s current position. For example, using GeolocationService.initialize, you can pass a callback function that gets triggered whenever a new location is received. This allows your app to log, display, or use the updated coordinates dynamically as the user moves. 


Now, we are creating a real-time path on Google Maps using the location data received from the GeolocationService. As each new coordinate is captured, we add it to an array of points and render it on the map using a Google Maps Polyline.

First, you need to install the react-native-background-geolocation plugin:
npm i react-native-maps

Next, follow the plugin documentation to configure your Android and iOS projects. You can find the official documentation here: Click Here

If you have successfully configured Google Maps in your project, you can now implement real-time path tracking using the location data received from the GeolocationService. The idea is simple — every time a new location update is received, push the latitude and longitude into an array and then draw a Polyline on the map that connects all these points. This will create a dynamic path that keeps updating as the user moves, giving you a live visual of their journey on Google Maps. Below is the implementation code to achieve this:

import { useEffect, useState } from 'react';
import GeolocationService from '../services/GeolocationService';
import { StyleSheet, View } from 'react-native';
import MapView, { Polyline, PROVIDER_GOOGLE } from 'react-native-maps';


const LiveTracking: React.FC<any> = () => {
    const [location, setLocation] = useState({
        latitude: 22.5017903,
        longitude: 88.348809,
    });
    const [locations, setLocations] = useState<Array<{ latitude: number, longitude: number }>>([]);

    useEffect(() => {
        GeolocationService.initialize((location) => {
            const newLocation = {
                latitude: location.coords.latitude,
                longitude: location.coords.longitude,
            };
            setLocation(newLocation);
            setLocations(prevLocations => [...prevLocations, newLocation]);
        });
    }, []);

    return (
        <View style={styles.container}>
            <MapView
                provider={PROVIDER_GOOGLE}
                style={styles.map}
                customMapStyle={[
                    {
                        featureType: 'road',
                        elementType: 'labels',
                        stylers: [{ visibility: 'off' }]
                    },
                    {
                        featureType: 'poi',
                        elementType: 'labels',
                        stylers: [{ visibility: 'off' }]
                    },
                    {
                        featureType: 'transit',
                        elementType: 'labels',
                        stylers: [{ visibility: 'off' }]
                    }
                ]}
                region={{
                    latitude: location.latitude,
                    longitude: location.longitude,
                    latitudeDelta: 0.015,
                    longitudeDelta: 0.0121,
                }}
            >
                <Polyline
                    coordinates={locations}
                    strokeColor="#FF0000"
                    strokeWidth={6}
                />
            </MapView>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    map: {
        width: '100%',
        height: '100%',
    },
});

export default LiveTracking;


Component Explanation:

This React Native component creates a live location tracking interface that displays a user's movement path on a map. Here's how it works:

1. Component Overview
const [location, setLocation] = useState({
    latitude: 22.5017903,  // Default location
    longitude: 88.348809,
});
const [locations, setLocations] = useState<Array<{ latitude: number, longitude: number }>>([]);
  • location: Stores the current GPS coordinates (starts with a default location)
  • locations: An array that accumulates all previous locations to create a movement trail.

2. Location Tracking Setup
useEffect(() => {
    GeolocationService.initialize((location) => {
        const newLocation = {
            latitude: location.coords.latitude,
            longitude: location.coords.longitude,
        };
        setLocation(newLocation);
        setLocations(prevLocations => [...prevLocations, newLocation]);
    });
}, []);
When the component mounts, it:
  • Initializes the GeolocationService with a callback function
  • Every time a new location is received, it updates both the current location and adds it to the locations array
  • This creates a continuous trail of the user's movement

3. Map Display
The component renders a Google Maps view with:

    1. Custom Map Styling: Removes labels for roads, points of interest, and transit to create a cleaner look
customMapStyle={[
    { featureType: 'road', elementType: 'labels', stylers: [{ visibility: 'off' }] },
    { featureType: 'poi', elementType: 'labels', stylers: [{ visibility: 'off' }] },
    { featureType: 'transit', elementType: 'labels', stylers: [{ visibility: 'off' }] }
]}
    
    2. Dynamic Region: The map centers on the current location with a fixed zoom level.
region={{
    latitude: location.latitude,
    longitude: location.longitude,
    latitudeDelta: 0.015,
    longitudeDelta: 0.0121,
}}

    3.  Movement Trail:
A red polyline shows the user's path.
<Polyline
    coordinates={locations}
    strokeColor="#FF0000"
    strokeWidth={6}
/>


Background Geolocation Service

The GeolocationService handles the heavy lifting:
  • Background Tracking: Uses react-native-background-geolocation to track location even when the app is in the background
  • High Accuracy: Configured for precise GPS tracking with 50-meter distance filter
  • Continuous Updates: Updates every 10 seconds (configurable)
  • Permission Management: Requests "Always" location permission for background tracking
  • Battery Optimization: Includes motion detection and activity recognition

Use Cases

This component would be ideal for:
  • Delivery tracking - showing delivery person's route
  • Fleet management - tracking vehicle movements
  • Field sales - monitoring sales representative visits
  • Fitness tracking - recording workout routes
  • Emergency services - real-time location sharing

Key Features
  • Real-time tracking with background location updates
  • Visual trail showing complete movement history
  • Clean map interface without distracting labels
  • Automatic map centering on current location
  • High-precision GPS tracking
The component provides a complete live tracking solution that works both in foreground and background, making it suitable for professional applications requiring continuous location monitoring.

Post a Comment

0 Comments