Build a real-time parcel tracking service in Nextjs

Deborah Emeni - Nov 22 '22 - - Dev Community

Real-time parcel tracking services are widely used in logistics companies worldwide. Both companies and customers can benefit from a viable service that provides tracking services and updates a parcel's status in real-time.

Appwrite is an open-source backend-as-a-service platform that provides developers various valuable services and APIs for building applications. Appwrite offers a Realtime Servicethat developers can use to build a parcel tracker that updates a parcel's status in real time without refreshing the page.

This article demonstrates using Next.js and Appwrite to create a real-time parcel tracking service. With Appwrite, you will build a real-time parcel tracker that lets you update the parcel's status directly from the Appwrite console.

GitHub

You can find the complete source code here.

Prerequisites

To follow along with this article, you'll need the following:

Getting started

Begin by clicking on Getting Started on Appwrite and running the commands in your terminal to install Appwrite. After installation, you should receive the following message:

Setting up the project on Appwrite

To set up the project on Appwrite, navigate to the URL where your Appwrite server is running by combining the port and localhost you specified when installing Appwrite as localhost:<your port number> on your browser.
Next, sign up to create a root account for your project:

Creating Appwrite account

After successfully signing up, you will have access to the Appwrite Console for creating your project:

Appwrite console

Click the Create Project button and provide a name for the project:

Naming the project

Creating a database

For your project, you need to create a database to store the data for your application, which Appwrite's Realtime service will monitor for status updates.
Navigate to the Appwrite console's menu and select Database:

Selecting database

Following that, create and name your database:

Creating database

Creating your first collection

After successfully creating your database, you can now create your first collection to store the parcel by clicking the Add Collection button and naming the collection:

Creating first collection

Creating a second collection

Create a new collection to store the Parcel events (which refer to the state of the parcel during delivery) by returning to your Parcel database and clicking the Add Collection button:

Creating second collection

Adding attributes to the collections

In the first Parcels collection, add Attributes to store information about the parcel:

Adding Attributes to the Collections

Add each of these attributes according to their data type:



parcel-name, customer-name, weight, quantity, time


Enter fullscreen mode Exit fullscreen mode

Adding attributes

Refer to the second ParcelEvents collection and add attributes for the parcelID, status, and time.

Adding attributes for second collection

Creating an index

You need to create an index to query data from the ParcelEvents collection. Navigate to the Indexes tab and click the Add Index button. Name the index, set the type, and choose the parcelId attribute from the list of attributes:

Creating an Index

Setting collection permissions

Navigate to the Parcels collection, click the Settings tab, and then click the Add Role button under Permissions:

Setting role permissions for parcels collection

Then, for the role, select the "any" option and enable the Create and Read permissions before clicking Update:

Selecting the roles

To set permissions on the ParcelEvents collection, go to the Settings tab and add the following roles: Create, Read, Update, and Delete:

Setting permission roles for the second ParcelEvents collection

Next, you'll use Next.js to begin building the project.

Building the project

Refer to the documentation to start building the project with Next.js, or simply run this command:



npx create-next-app@latest


Enter fullscreen mode Exit fullscreen mode

When the command completes successfully, open the directory in your code editor, and your project structure should look like this:

The project structure for the application

Setting the environment variables

In the root directory, create a **.env** file to store the environment variables for the following:

  • API Endpoint URL
  • Database ID
  • Parcels collection ID
  • ParcelEvents collection ID
  • Project ID

To create the environment variables, you need to add "NEXT_PUBLIC" as a prefix, which tells Next.js that the environment variables belong to the client side:

Setting the environment variables

To obtain your API Endpoint, navigate to the menu and select Settings, and copy the URL:

Obtaining the API endpoint

Return to the menu and select Database to find your Database ID. Navigate to the Settings tab of your Parcel database and copy the Database ID:

Getting the Database ID

Next, select the Parcels collection on the Collections tab, then go to Settings and copy your Collection ID:

Getting the Collection ID for the first collection

Copy the Collection ID for the second ParcelEvents collection:

Getting the Collection ID for the first collection

To obtain the Project ID, return to the Home page and select Settings, then copy the Project ID:

Getting the Project ID

Adding Tailwind CSS to the Project

We will use the Tailwind CSS library for this project. Install and initialize Tailwind in the root directory of your project by running the following commands:



npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p


Enter fullscreen mode Exit fullscreen mode

After running these commands, the "tailwind.config.js" file will appear in your project directory.

Open your code editor and paste the following configuration into the tailwind.config.js file:



   /** @type {import('tailwindcss').Config} */
   module.exports = {
    content: ["./pages/**/*.{html,js,jsx}"],
    theme: {
      extend: {},
    },
    plugins: [],
   }


Enter fullscreen mode Exit fullscreen mode

Paste the following code at the top of the globals.css file in the styles folder:



@tailwind base;
@tailwind components;
@tailwind utilities;


Enter fullscreen mode Exit fullscreen mode

Adding Appwrite Connection and Configurations

To install Appwrite Client in your project, run the following command in the root directory:



npm install appwrite


Enter fullscreen mode Exit fullscreen mode

Create a Utils folder in the root directory containing two files: appwrite-connection.js (for connecting your project to Appwrite) and config.js (configuration file that will centralize the data in the .env file).

Add the configuration defined in the config.js file in the GitHub repository.

Creating the landing page

Replace the code in the pages > index.js file with this code. You are creating a functional component Home() in the index.js file that does the following:

  • Creates isLoading, parcelID, and parcel states.
  • Creates a function called getParcelDetails() that accepts the parcel ID as a tracking No parameter and performs the following operations:
    • The setLoading() function initially sets the isLoading state to true on the calling of the getParcelDetails() function.
    • Queries the database to retrieve the parcel according to the tracking number that the user provides as input.
    • Saves the response in the setParcel() state and routes and carries the data to the tracker page (where users can view the parcel status).
    • Any error message will appear as an alert and log to the console. After a successful process, the setLoading() state is set to false.
    • The setLoading function will set the isLoading state to true once the operation is complete.
    • The condition in the '' section checks whether the isLoading state is true or false. When true, the <input> tag retrieves the tracking number the user provides as input and uses the setParcelID() function to set the parcelID state to the tracking number.
    • When the user clicks the Track Parcel link, the onClick() event calls the getParcelDetails() function with the parcelID as a parameter.

Creating the tracking page

In the Pages directory, create a new file called "tracker.js" that will contain real-time updates on the parcel, including the parcel's status from ordering to delivery. In your tracker.js file, insert the code written in this repository.

This code does the following:

  • Creates a **Tracker()** functional component, which does the following:
    • Creates a notifications state to store the parcel events and a parcelData state to store information about the parcel.
  • Creates a getParcelEvents() function that accepts the parcelID as the tracking No. parameter that implements the following:
    • Fetches the list of documents from the ParcelEvents collection according to the **ParcelId**.
    • The Date variable maps through each document in the list.
    • The setNofications() function updates the notification state with the data.
  • The registerSubscriber() function listens for the real-time events on Appwrite by subscribing to the documents events. For every trigger in the documents events, the callback calls the getParcelEvents() function, passing in the id from the parcelData state.
  • The useEffect() monitors the router.query and executes a callback which sets the parcelData state, calls the getParcelsEvents() function, and calls the registerSubscriber() function.

Testing the project

To test the project, add data to your Parcels collection and click Add Document:

Adding document

Then set the following:

Setting fields in the document

Afterward, click Create and copy the "$id":

Getting the document ID

Next, select the ParcelEvents collection and create a document using the "$id" you copied:

Creating a document in the second collection

Click Create, and you should have the following document:

Viewing the created document

Start the development server for the project by running this command:



npm run dev


Enter fullscreen mode Exit fullscreen mode

Visit the URL "http://localhost:3001" to view the application:

Conclusion

This article demonstrated how to build a real-time parcel tracking service with Next.js and Appwrite.

Resources

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .