Build a Live Location Tracker with React & Firebase: A Step-by-Step Guide

By admin December 22, 2025 13 min read

Build a Live Location Tracker with React & Firebase: A Step-by-Step Guide

Have you ever wondered how apps like Uber or food delivery services show moving vehicles on a map in real-time? The technology behind it is fascinating, but the good news is, you can build your own version! In this comprehensive tutorial, we’ll create a fully functional Live Location Tracker using React.js for our dynamic frontend and Google Firebase as our powerful, real-time backend.

This project is perfect for beginner to intermediate developers looking to level up their skills. You’ll learn how to integrate multiple modern web technologies: React for building user interfaces, the browser’s Geolocation API to get location data, Firebase Firestore for live database updates, and the Google Maps JavaScript API for visualization. By the end, you’ll have a deployable web app that can track a device’s location on a live-updating map.

To watch the full tutorial on YouTube, click here.

Let’s dive in and turn this idea into reality!

Project Overview & How It Works

Before we write any code, let’s understand what we’re building and the data flow behind it. Our application will have two main perspectives:

  • The Tracker (Sender): This is a simple page that, once allowed, continuously sends the device’s latitude and longitude to our Firebase database.
  • The Dashboard (Viewer): This is a map view that listens for changes in the Firebase database and updates the position of a marker on the map in real-time.

The magic of “live” updates comes from Firebase Firestore’s real-time listeners. When the tracker updates a coordinate document, Firebase instantly notifies all connected dashboard clients, making the marker jump to its new location without needing to refresh the page.

Prerequisites: What You Need to Get Started

To follow along smoothly, you’ll need a few things set up on your machine. Don’t worry if some of these are new; we’ll cover the setup steps.

  • Node.js and npm: The foundation for running our React development environment. You can download and install them from the official Node.js website.
  • A Google Account: This is required to use Firebase and the Google Maps Platform.
  • A Code Editor: VS Code is highly recommended for its excellent React and Firebase support.
  • Basic Knowledge: Familiarity with HTML, CSS, and fundamental JavaScript (ES6+) concepts will be very helpful. A little prior experience with React, like understanding components and hooks, is a plus but not strictly required-we’ll explain as we go!

Got everything ready? Fantastic. Let’s start by setting up the brain of our operation: Firebase.

Step 1: Setting Up Your Firebase Project

Firebase will act as our serverless backend, handling authentication, database, and hosting. Here’s how to configure it.

Create a New Firebase Project

  1. Go to the Firebase Console.
  2. Click “Add project”.
  3. Give your project a name (e.g., live-location-tracker).
  4. You can disable Google Analytics for this project to keep it simple, then click “Create project”.

Set Up Firestore Database

  1. Once the project is created, go to the “Build” section in the left sidebar and select “Firestore Database”.
  2. Click “Create database”.
  3. Start in test mode for now. This allows open read/write access, which is fine for development. Remember: You must secure these rules before any public deployment.
  4. Choose a cloud Firestore location close to you and click “Enable”.

Get Your Firebase Configuration Object

This is the key that connects your React app to your Firebase project.

  1. On the Firebase project overview page, click the web icon (</>) to register a web app.
  2. Give it a nickname (e.g., “Live Tracker Web App”) and click “Register app”.
  3. You’ll be shown a configuration object containing API keys and identifiers. It will look like the code below. Copy this object-we’ll need it soon.
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "your-project-id.firebaseapp.com",
  projectId: "your-project-id",
  storageBucket: "your-project-id.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

Important Security Note: The API key in this configuration is safe to expose in your frontend code. Firebase security is enforced through Firestore Security Rules, not by hiding this configuration. However, you should always set up proper rules before going live.

Step 2: Setting Up Your React Application

With Firebase ready, let’s create the React application that will be our frontend.

Create the React App

Open your terminal or command prompt, navigate to your projects folder, and run the following command:

npx create-react-app live-location-app
cd live-location-app

This creates a new React project named live-location-app and moves you into its directory.

Install Required Dependencies

We’ll need a few packages: Firebase for backend communication, React Router for navigation, and the Google Maps API library.

npm install firebase react-router-dom @react-google-maps/api
  • firebase: The official SDK to connect to our Firebase backend.
  • react-router-dom: Allows us to have multiple pages (Tracker and Dashboard) in our single-page app.
  • @react-google-maps/api: A popular, well-maintained library that makes it easy to integrate Google Maps into React components.

Set Up Environment Variables

To keep our Firebase keys secure and configurable, we’ll use environment variables. In the root of your live-location-app project, create a file named .env.local.

REACT_APP_FIREBASE_API_KEY=YOUR_API_KEY
REACT_APP_FIREBASE_AUTH_DOMAIN=your-project-id.firebaseapp.com
REACT_APP_FIREBASE_PROJECT_ID=your-project-id
REACT_APP_FIREBASE_STORAGE_BUCKET=your-project-id.appspot.com
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=YOUR_SENDER_ID
REACT_APP_FIREBASE_APP_ID=YOUR_APP_ID
REACT_APP_GOOGLE_MAPS_API_KEY=YOUR_GOOGLE_MAPS_API_KEY

Replace the placeholder values with the ones from your Firebase config object you copied earlier. For the REACT_APP_GOOGLE_MAPS_API_KEY, you’ll need to get a Google Maps JavaScript API key from the Google Cloud Console (ensure the Maps JavaScript API is enabled for that key).

Tip: Any environment variable in Create React App must be prefixed with REACT_APP_ to be embedded into the build. After saving this file, you must restart your development server (npm start) for the changes to take effect.

Step 3: Building the Core Firebase Configuration File

Now, let’s create a file that initializes Firebase and exports the services we’ll use. In your src folder, create a new file: firebase.js.

// src/firebase.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);

// Export the database instance so we can use it in our components
export { db };

This file does the crucial job of connecting our app to Firebase using the keys from our environment variables. We export db, which is our gateway to the Firestore database.

Step 4: Creating the Application Components

Our app will have three main components: a navigation layout, the Tracker page, and the Dashboard page.

Component 1: App.js (with Routing)

We’ll modify the main App.js file to set up routing between our pages.

// src/App.js
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Tracker from './components/Tracker';
import Dashboard from './components/Dashboard';
import './App.css';

function App() {
  return (
    <Router>
      <div className="App">
        <nav style={{ padding: '20px', background: '#f0f0f0' }}>
          <Link to="/" style={{ marginRight: '20px' }}>Tracker</Link>
          <Link to="/dashboard">Dashboard</Link>
        </nav>
        <Routes>
          <Route path="/" element={<Tracker />} />
          <Route path="/dashboard" element={<Dashboard />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

Component 2: The Tracker Component

This component is responsible for getting the user’s location and sending it to Firebase. Create a src/components folder and inside it, create Tracker.js.

// src/components/Tracker.js
import { useState, useEffect } from 'react';
import { db } from '../firebase';
import { doc, setDoc } from "firebase/firestore";

const Tracker = () => {
  const [latitude, setLatitude] = useState(null);
  const [longitude, setLongitude] = useState(null);
  const [isTracking, setIsTracking] = useState(false);
  const [status, setStatus] = useState('Press "Start Tracking" to begin.');

  // We'll use a single document ID for simplicity. In a real app, this would be user-specific.
  const docId = 'current-location';

  useEffect(() => {
    let watchId;
    if (isTracking) {
      setStatus('Getting location...');
      if (!navigator.geolocation) {
        setStatus('Geolocation is not supported by your browser.');
        return;
      }

      // Success handler for the geolocation watch
      const success = async (position) => {
        const { latitude, longitude } = position.coords;
        setLatitude(latitude);
        setLongitude(longitude);
        setStatus('Location acquired. Sending to Firebase...');

        try {
          // Write the location to Firestore in a document with our fixed ID
          await setDoc(doc(db, "locations", docId), {
            latitude,
            longitude,
            timestamp: new Date()
          });
          setStatus(`Location sent! Lat: ${latitude.toFixed(4)}, Lng: ${longitude.toFixed(4)}`);
        } catch (error) {
          console.error("Error writing document: ", error);
          setStatus('Failed to send location.');
        }
      };

      // Error handler for the geolocation watch
      const error = (err) => {
        console.error(`ERROR(${err.code}): ${err.message}`);
        setStatus(`Error: ${err.message}`);
      };

      const options = {
        enableHighAccuracy: true,
        maximumAge: 0
      };

      // Start watching the position
      watchId = navigator.geolocation.watchPosition(success, error, options);
      setStatus('Tracking active...');
    } else {
      // Clean up the geolocation watcher when tracking stops
      if (navigator.geolocation && watchId) {
        navigator.geolocation.clearWatch(watchId);
      }
      setStatus('Tracking stopped.');
    }

    // Cleanup function to clear the watcher if the component unmounts
    return () => {
      if (navigator.geolocation && watchId) {
        navigator.geolocation.clearWatch(watchId);
      }
    };
  }, [isTracking, docId]); // The effect depends on the isTracking state

  const toggleTracking = () => {
    setIsTracking(!isTracking);
  };

  return (
    <div style={{ padding: '40px' }}>
      <h2>Live Location Tracker (Sender)</h2>
      <p>This page will send your device's location to the Firebase database.</p>
      <button onClick={toggleTracking} style={{
        padding: '10px 20px',
        fontSize: '16px',
        backgroundColor: isTracking ? '#dc3545' : '#28a745',
        color: 'white',
        border: 'none',
        borderRadius: '5px',
        cursor: 'pointer'
      }}>
        {isTracking ? 'Stop Tracking' : 'Start Tracking'}
      </button>
      <p><strong>Status:</strong> {status}</p>
      {latitude && longitude && (
        <p>
          <strong>Current Coordinates:</strong><br />
          Latitude: {latitude.toFixed(6)}<br />
          Longitude: {longitude.toFixed(6)}
        </p>
      )}
    </div>
  );
};

export default Tracker;

This component uses the browser’s geolocation.watchPosition() API to continuously get location updates. Every time a new location is received, it writes the data to a specific Firestore document (locations/current-location). The setDoc function overwrites the document each time, which is fine for our single-tracker use case.

Component 3: The Dashboard Component

This component displays the live map and listens for updates from Firebase. Create Dashboard.js in the src/components folder.

// src/components/Dashboard.js
import { useState, useEffect } from 'react';
import { db } from '../firebase';
import { doc, onSnapshot } from "firebase/firestore";
import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api';

// Map container style
const containerStyle = {
  width: '100%',
  height: '80vh'
};

// Default center (will be overridden by live data)
const defaultCenter = {
  lat: 0,
  lng: 0
};

const Dashboard = () => {
  const [location, setLocation] = useState(defaultCenter);
  const [loaded, setLoaded] = useState(false);
  const docId = 'current-location'; // Must match the ID used in Tracker.js

  useEffect(() => {
    // Set up a real-time listener on the specific Firestore document
    const unsubscribe = onSnapshot(doc(db, "locations", docId), (docSnapshot) => {
      if (docSnapshot.exists()) {
        const data = docSnapshot.data();
        const newLocation = {
          lat: data.latitude,
          lng: data.longitude
        };
        setLocation(newLocation);
        if (!loaded) setLoaded(true); // Map is ready to be centered
      } else {
        console.log("No such document!");
      }
    }, (error) => {
      console.error("Error listening to document: ", error);
    });

    // Clean up the listener when the component unmounts
    return () => unsubscribe();
  }, [docId, loaded]);

  return (
    <div style={{ padding: '20px' }}>
      <h2>Live Location Dashboard (Viewer)</h2>
      <p>This map updates in real-time as new location data is received from Firebase.</p>
      {!loaded && <p>Waiting for initial location data...</p>}

      <LoadScript
        googleMapsApiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY}
      >
        <GoogleMap
          mapContainerStyle={containerStyle}
          center={location}
          zoom={15}
        >
          {loaded && <Marker position={location} />}
        </GoogleMap>
      </LoadScript>
      <p style={{ marginTop: '10px' }}>
        <strong>Live Coordinates:</strong> {location.lat.toFixed(6)}, {location.lng.toFixed(6)}
      </p>
    </div>
  );
};

export default Dashboard;

The key here is the onSnapshot function. It sets up a listener that fires every time the locations/current-location document changes. When it does, we extract the new latitude and longitude and update our component’s state. React then re-renders the <GoogleMap> and <Marker> components, smoothly moving the marker to the new position.

Step 5: Understanding the Real-Time Flow

Let’s connect the dots on how the live update works:

  1. User grants permission on the Tracker page and clicks “Start Tracking”.
  2. The browser’s Geolocation API begins sending coordinates to the Tracker component.
  3. Each new coordinate is written to a specific Firestore document using setDoc.
  4. Firestore detects the document change and instantly notifies all subscribed clients.
  5. The Dashboard component’s onSnapshot listener receives the new data.
  6. The component’s state updates, causing React to re-render the map with the marker at the new position.

This entire process happens in milliseconds, creating the seamless “live” effect.

Pro-Tip for Scaling: Our example uses a single, hardcoded document ID. For a multi-user app (e.g., tracking delivery drivers), you would create a new document for each user under a collection (e.g., drivers/{driverId}/location). The Dashboard would then listen to a query across that collection to show multiple markers.

Step 6: Running and Testing Your Application

It’s time to see your hard work in action! In your terminal, ensure you’re in the project root (live-location-app) and run:

npm start

Your browser should open to http://localhost:3000 showing the Tracker page.

  1. On the Tracker page, click “Start Tracking”. Grant location permissions when your browser asks.
  2. You should see the status update and coordinates appear.
  3. Open a new browser window or tab and navigate to http://localhost:3000/dashboard.
  4. Move the window with the Tracker page and watch the marker move on the Dashboard map in real-time! The update is instant.

Step 7: Deploying Your Live Tracker to the Web

To share your app, let’s deploy it using Firebase Hosting-it’s free and integrates perfectly.

  1. Install the Firebase CLI globally: npm install -g firebase-tools
  2. Log in to your account: firebase login
  3. Initialize your project for hosting: firebase init
    • Select Hosting from the features list.
    • Choose your existing Firebase project.
    • Set your public directory as build (this is where Create React App outputs production files).
    • Answer Yes to configure as a single-page app (this helps with React Router).
    • Answer No to overwriting index.html.
  4. Build your React app for production: npm run build
  5. Deploy to Firebase Hosting: firebase deploy --only hosting

After deployment, Firebase will give you a live URL (e.g., https://your-project-id.web.app). Share this link! Anyone with the Dashboard URL can now see the live location updates from the Tracker page.

Critical Next Step: Before sharing your app widely, you must go back to the Firebase Console and update your Firestore Security Rules (under the “Rules” tab) to restrict who can read and write data. The default “test mode” rules leave your database open to the public, which is a security risk. Check the Firebase documentation for guidance.

Conclusion and Next Steps

Congratulations! You’ve successfully built a live location tracking application. You’ve integrated a React frontend with Firebase’s real-time database and the Google Maps API-a powerful combination used in countless professional applications.

You can expand this project in many exciting ways:

  • User Authentication: Add Firebase Authentication to track multiple users individually.
  • Historical Paths: Instead of overwriting, save locations as a collection to draw a path of where the tracker has been.
  • Multiple Markers: Modify the Dashboard to listen to a collection and display several moving markers at once.
  • Custom UI/UX: Style the app with a CSS framework like Tailwind CSS or Material-UI to make it look polished.

The skills you’ve practiced here-handling real-time data, working with external APIs, and managing application state-are incredibly valuable in modern web development. We hope this tutorial from Halogenius Ideas has sparked more ideas for what you can build.

To watch the full tutorial on YouTube, click here.

Have fun coding, and feel free to explore our other web development tutorials to continue your learning journey!

Watch The Video

Watch on YouTube

How did this article make you feel?

Share This Post

About admin

Founder and Lead Developer at Halogenius Ideas, bridging the gap between professional web design and accessible tech education. With years of experience in full-stack development and a passion for teaching, I lead a team dedicated to building stunning digital experiences while empowering the next generation of developers through comprehensive tutorials and courses. When I'm not coding or creating content, you'll find me exploring new technologies and mentoring aspiring developers.

Leave a Reply

Your email address will not be published. Required fields are marked *

seventy one + = 78
Powered by MathCaptcha