> ## Content Index
> Fetch the complete content index at: https://blog.afi.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# Driver tracking with Google Maps
- URL: https://blog.afi.io/blog/adding-a-live-driver-tracking-map-to-your-website/
- Published: 2021-03-16T04:19:44.000Z
- Updated: 2024-09-21T14:00:58.000Z
- Description: A simple guide on building a delivery driver tracking app using Google Maps.
- Author: Afian Anwar
- Tags: tech

You've built [an iOS app that tracks the realtime location of your drivers](https://blog.afi.io/blog/implementing-driver-live-tracking-on-ios/) and [hooked it up to a simple backend using Firebase](https://blog.afi.io/blog/building-live-driver-tracking-backend/). The final step in implementing a live delivery driver tracking app that would make the NSA proud is to write some frontend code to display your driver locations on Google Maps so that you can track them from anywhere.

Part 1: [Implementing driver live tracking on iOS](https://blog.afi.io/blog/implementing-driver-live-tracking-on-ios/)  
Part 2: [Building a live driver tracking backend](https://blog.afi.io/blog/building-live-driver-tracking-backend/)  
**Part 3: Driver tracking with Google Maps (this article)**

![](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2021/03/Screen-Shot-2021-03-16-at-11.39.57-PM.png)

For this tutorial, we will scaffold the delivery driver tracking app using a simple React web app that displays the realtime location of your drivers on a Google map. The last known location of each driver will be shown as a colored marker, and the marker's position will move as your drivers move, without having to refresh the page. As usual, [sample code](https://github.com/afilabs/gps%5Ftracking%5Fweb?ref=blog.afi.io) is available for you to download and run.

![Driver tracking location tracker on Google Maps](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2021/03/web.png)

What we are going to build - live driver tracking on a map interface

### Getting started

The web app we are building uses starter code from the [Create React App](https://reactjs.org/docs/create-a-new-react-app.html?ref=blog.afi.io) project. This tutorial assumes some understanding of how React works and how to run a single page app, but even if you aren't a React guru, you should be able to follow the [readme instructions](https://github.com/afilabs/gps%5Ftracking%5Fweb/blob/master/README.md?ref=blog.afi.io) to run it locally and play around with it.

> [Afi Labs](https://www.afi.io/?ref=blog.afi.io) builds custom transportation and logistics management software. From route optimization, live tracking to proof of delivery and driver apps, we've got you covered!   
> 
> [👋 Say Hello!](https://afi.io/?ref=blog.afi.io#contact-us) 

### Configuring your .env file

The first thing we need to do is create a .env file to store the API keys and endpoints for the various services we will use. Using your favorite text editor, copy and paste the following and save the file as `.env` in the root folder of our app.

```
REACT_APP_NAME='GPS Tracking App'
REACT_APP_GOOGLE_API_KEY='GOOGLE_API_KEY'
REACT_APP_FIREBASE_API_KEY='FIREBASE_API_KEY'
REACT_APP_FIREBASE_AUTH_DOMAIN='FIREBASE_AUTH_DOMAIN'
REACT_APP_FIREBASE_DATABASE_URL='FIREBASE_DB_URL'

```

We need a Google API key to use Google Maps. You can follow [these instructions](https://developers.google.com/maps/documentation/maps-static/get-api-key?ref=blog.afi.io) to get one and replace `GOOGLE_API_KEY`. Google Maps isn't free, but if you put up a credit card you can get over $200 in usage credits each month, which is more than enough for light production usage.

Next, log into [https://console.firebase.google.com/](https://console.firebase.google.com/?ref=blog.afi.io) to retrieve your Firebase credentials. `FIREBASE_API_KEY` can be found on the "General" tab of your Realtime Database project settings (click the gear icon on the left navigation panel - read my [previous blog post](https://blog.afi.io/blog/building-live-driver-tracking-backend/) on how to set up Firebase) under the heading "Web API Key".

![firebase setup for driver live driver tracking app project](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2021/03/Screen_Shot_2021-03-15_at_10_38_40_PM.png)

`FIREBASE_DB_URL` can be found in the "Data" tab of your Realtime Database project. `FIREBASE_AUTH_DOMAIN` is the same thing, but with the https:// omitted.

![real time database setup for driver live tracking project to build a driver tracking app](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2021/03/Screen_Shot_2021-03-16_at_7_17_12_PM.png)

These configuration variables are used in `firebase.js` to correctly load the Firebase SDK and point it to our Firebase account.

```javascript
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';

const config = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
};

const app = firebase.initializeApp(config);

```

### How our code is organized

This isn't a React tutorial, but it's worth spending a few minutes explaining how our code works. There is only a single page on our web app, `index.html` found at `public/index.html`. The code to create and display our map (`index.js`, `app.js`, `livemap.js`) is found in the `/src` folder . When you use webpack to compile the code, it appends `index.js` to `index.html`.

### index.html

In `index.html`, we see:

```javascript
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

What this code does is it looks for the <div> element with the `id` of `root` and it inserts the React component called `<App/>`. The code for `<App/>` is found in `App.js`, and it is here that we find our API calls to Firebase.

### App.js

```javascript
import React, { useEffect, useState } from "react";
const App = () => {
    const [users, setUsers] = useState([]);

    useEffect(() => {
      firebase.database().ref("users").on("value", snapshot => {
        let users = [];
        snapshot.forEach(snap => {
          users.push(snap.val());
        });
        setUsers(users);
      });
    }, []);

```

Here's what's going on.

```javascript
const [users, setUsers] = useState([]);

```

The `useState` React [hook](https://reactjs.org/docs/hooks-state.html?ref=blog.afi.io) lets you add state to functions. It returns a pair of values, for which I have used [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring%5Fassignment?ref=blog.afi.io) to create two local variables. For example, `users` lets the component access the current list of drivers (the list of `user_id`s in the `users` object in Firebase), which conveniently also stores a references to the `location` object with the driver's most recent `lat`/`lng`. The `setUsers` variable is a function that is used to update the list of drivers.

After that,

```javascript
useEffect(() => {
      firebase.database().ref("users").on("value", snapshot => {
        let users = [];
        snapshot.forEach(snap => {
          users.push(snap.val());
        });
        setUsers(users);
      });
    }, []);
```

we use React's built-in `useEffect` Hook to tells React to perform some action or “side effect” after a component has been rendered in the browser. The `useEffect` Hook accepts two parameters. The first is a function that accepts no parameters and defines what the side effect actually does. The second is an array of dependencies i.e. variables that will be used in the first parameter (we have none, so we pass in an empty array).

Let's look carefully at our "side effect" code.

```javascript
firebase.database()
```

To read or write data from the Realtime Database, you need an instance of `firebase.database.Reference`.

```javascript
firebase.database().ref("users")
```

A reference (the `ref()` method) refers to the location inside our database. Here, we are pointing to the `users` object, which is a list of key value pairs of `user_id`s and their `location`s.

```javascript
firebase.database().ref("users").on("value", snapshot => { // some stuff in here })
```

The `on()` method reads data at a path and listens for changes to `users` and any child objects of `users`. This is awesome because if any of your drivers move, their `location` object will update and we can render their new locations in realtime on our map. Any time you read data from the database, you receive the data as a `DataSnapshot`, which in our example above is stored in the `snapshot` function.

```javascript
firebase.database().ref("users").on("value", snapshot => {
        let users = [];
        snapshot.forEach(snap => {
          users.push(snap.val());
        });
        setUsers(users);
      });
```

Next, I create an empty local array called `users` and iterate over my `snapshot`, pushing the value of each item (retrieved by calling `snap.val()`) into the `users` array. Each item is a key - value pair like the one shown below.

![](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2021/03/Screen-Shot-2021-03-17-at-9.40.48-AM.png)

Lastly, I call `setUsers(users)` to update the `users` hook. Now we are ready to display our drivers on the map by passing the `locations` object as a prop to our `<LiveMap/>` component. The code for `LiveMap` lives in `src/livemap.js`.

```javascript
return (
    <div className="App">
      <div className="LiveMap">
        <LiveMap locations={users.map(u => u.location)} />
      </div>
    </div>
  );
```

### livemap.js

This is just a simple Google Maps React component (very similar to the Google [Map React project](https://www.npmjs.com/package/google-map-react?ref=blog.afi.io)) that iterates over `locations`, extract each `{location.lat}, {location.lng}` and plots them on a map.

```javascript
return (
      <GoogleMap ref={elem => this.map = elem} >
        {this.props.locations.map((location, index) => (
          <Marker
            icon={{
              url: driver,
              scaledSize: { width: 35, height: 44 },
            }}
            key={index}
            position={{ ...location }}
            onClick={() => this.setState({ selectedLocation: location })}
          >
            {this.state.selectedLocation === location &&
              <InfoWindow onCloseClick={() => this.setState({ selectedLocation: null })}>
                <div style={{ color: 'black' }}>
                  {location.lat}, {location.lng} 
                </div>
              </InfoWindow>
            }
          </Marker>
        ))}
      </GoogleMap>
    );
```

The magic about all this is that there is no need to poll the server to get updated locations. When data changes in Firebase, our `ref` in `App.js` listens for changes and everything updates automagically.

So there you have it! You now have live delivery driver tracking app for your fleet. This is a must have for more advanced features like dispatch, customer notifications and delivery live tracking by your customers.

👋 **As** **always, if you have any questions or suggestions for me, please** [**reach out**](https://afi.io/?ref=the-afi-labs-blog#contact-us) **or** [**say hello on LinkedIn**](https://www.linkedin.com/in/afian-anwar-a023b143/?ref=the-afi-labs-blog)**.**

Part 1: [Implementing driver live tracking on iOS](https://blog.afi.io/blog/implementing-driver-live-tracking-on-ios/)  
Part 2: [Building a live driver tracking backend](https://blog.afi.io/blog/building-live-driver-tracking-backend/)  
**Part 3: Driver tracking with Google Maps (this article)**