Real-time Location tracking App build with MongoDB Change Streams and Socket.io
Tags: atlashackathon22, javascript, react, mongodb
Published: 2022-12-06 12:08:05

## What I built
A Real-time Delivery Service application. The concept is similar to Uber but for carrying packages locally. I have used MongoDB Change Streams to update location and Shipment status notifications in real-time. For this I have to build two UIs one for users and other to simulate delivery associates.

![real-time location update](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a91fufjgk5yjplo3gqyg.gif)
> Left Window: User App
> Right Window: Driver Simulator


### Category Submission:
- **Real-time** [Change Stream](https://www.mongodb.com/docs/manual/changeStreams/)

### Video Explanation
{% embed https://youtu.be/Ydi60M4MrHc %}

### App Link
- [User App](https://delivery-service-frontend.netlify.app/)
- [Delivery Agent Simulator](https://delivery-associate-simulator.netlify.app/)

### How to Simulate the demo

> Note: Browser's Geolocation API is 🚫 **not used** to avoid storing any user location information (GDPR). 
> To make things easy I have made Chennai, a city in India as the base location. Please simulate the app in the location which gets loaded
> 🚫 Signup is disabled. Please use the credentials provided below in the post
> The Backend is hosted on Render.com free tier so there might be some cold start issues when trying to login

- [Open the Driver Simulator](https://delivery-associate-simulator.netlify.app/)
- Enter this associate id to continue `637f9183e03774d5c46ddffc`
- [Open the User app](https://delivery-service-frontend.netlify.app/)
- Use the below credentials to login
```
Email: carl@example.com
Password: s24x546olk45edxf
```
- In the User app click on the "New delivery" button
- Confirm pickup location
- Confirm drop location
- You will see a notification on the driver simulator 
- Accept the new delivery request
- In the simulator move the truck icon across the marker (GIF provided below)
- You will see the truck movement on the user map in real-time 
- In the simulator Update the delivery status
- You will see the status information getting updated in the user app real time

### Screenshots
Architecture Diagram
![Architecture Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kaqh4xv299ld3g3ji72s.png)
Live location and Status updates
![Delivery with live updates](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cvac7prsqn0smr3pcjz.gif)
Driver Simulator
![Driver Simulator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmhtve325dbsdq2mckj0.gif)

## Description
There are three repos to this project.
1. **The Backend**
The Backend is connected to [MongoDB Atlas](https://www.mongodb.com/atlas/database) and does CRUD operations on API calls. The Backend service also uses [Socket.io](https://socket.io/) to handle socket connections. MongoDB Change Streams events are broadcasted via Socket.io. There are three main Change Stream subscriptions in this application
 - Delivery Agent's location update change stream to track package
 - Shipment Status updates to update status in User UI
 - New Shipment Created notification broadcasted to Agents to Accept or Reject a shipment.

2. **User UI**
Both frontends are build React and uses [Leaflet](https://leafletjs.com/) for Maps. The User UI is used to do CRUD events like Signup, Login, Create new deliveries and to show real-time events.
 - Real-time information updates on Delivery Status. 
 - Real-time location of the the package being delivered can be seen on the Map
 
3. **Delivery Associate Simulator**
This is used to simulate a delivery agent. This app receives real-time notification when any new delivery gets initiated. Agents can Accept or Reject deliveries and Update delivery status. 
The important functionality the simulator provides is the ability to simulate the **GPS location update event of an agent**. The current location of an Agent is denoted by a Truck Marker on the map. Dragging the marker across the Map emits an event to update the Agent's current location in the DB.

### Link to Source Code
- [Backend Main](https://github.com/ashiqsultan/delivery-service-backend)
- [Frontend](https://github.com/ashiqsultan/delivery-service-frontend)
- [Driver Simulator](https://github.com/ashiqsultan/delivery-service-associate-simulator)


### Permissive License
- MIT License

## Background
### What made me decide to build this particular app?
I wanted to try MongoDB's **Change Stream** functionality, so I was thinking about building a real-time application. And since MongoDB supports GeoJSON out of the box **I wanted to challenge myself and decided to build a real-time application which uses location data.**
#### What inspired me?
Uber and Food delivery Apps. There's a company in India named **Dunzo** who do similar delivery service.

### How I built it
I have used MongoDB Atlas free tier for this application. 
Something new I learned building this app is [MongoDB Change Stream](https://www.mongodb.com/docs/manual/changeStreams/). 
I have used Socket.io to create Socket Connection rooms and broadcast events. Socket room name is just the Shipment id and user subscribes to the respective room i.e Shipment id he has created. When there's a MongoDB Change Stream event on Shipment Collection I'm publishing the updated document to the room using the shipmentId which got updated.

```
Shipment.watch([], watchOptions).on('change', (data: any) => {
    const fullDocument = data.fullDocument;
    if (data.operationType === 'update') {
      io.to(String(fullDocument._id)).emit(
        socketEvents.SHIPMENT_UPDATED,
        fullDocument
      );
    }
  });
```
 

I have used Render to deploy the backend and Netlify to deploy the frontend applications

### Additional Resources/Info
- [MongoDB Change Stream](https://www.mongodb.com/docs/manual/changeStreams/)
- [Mongoose Change Stream Docs](https://mongoosejs.com/docs/change-streams.html)
- [Socket.IO](https://socket.io/)