Creating a real-time notification system

morshedulmunna

Morshedul Munna

Posted on September 8, 2024

Creating a real-time notification system

Creating a real-time notification system involves setting up a server that can push notifications to clients as events occur. Using Express.js for the backend server, MongoDB for data storage, Socket.io for real-time communication, and React for the frontend provides a robust stack for building such a system.

Below is a step-by-step guide to creating a notification system with these technologies.


Table of Contents

  1. Prerequisites

  2. Setting Up the Backend

* [Initialize the Project](#initialize-the-project)

* [Set Up Express Server](#set-up-express-server)

* [Integrate Socket.io](#integrate-socketio)

* [Connect to MongoDB](#connect-to-mongodb)

* [Create Notification Schema](#create-notification-schema)

* [API Endpoints](#api-endpoints)
Enter fullscreen mode Exit fullscreen mode
  1. Setting Up the Frontend
* [Initialize React App](#initialize-react-app)

* [Install Dependencies](#install-dependencies)

* [Set Up Socket.io Client](#set-up-socketio-client)

* [Display Notifications](#display-notifications)
Enter fullscreen mode Exit fullscreen mode
  1. Testing the Notification System

  2. Conclusion


Prerequisites

  • Node.js and npm installed on your machine.

  • MongoDB installed locally or have access to a MongoDB Atlas cluster.

  • Basic knowledge of JavaScript, Node.js, Express.js, MongoDB, Socket.io, and React.


Setting Up the Backend

Initialize the Project

Create a new directory for your project and initialize it with npm:

bashCopy codemkdir notification-system
cd notification-system
npm init -y
Enter fullscreen mode Exit fullscreen mode

Set Up Express Server

Install Express and other necessary dependencies:

bashCopy codenpm install express cors mongoose socket.io
Enter fullscreen mode Exit fullscreen mode

Create an index.js file for your server:

javascriptCopy code// index.js
const express = require('express');
const http = require('http');
const cors = require('cors');

const app = express();
app.use(cors());
app.use(express.json());

const server = http.createServer(app);

server.listen(5000, () => {
  console.log('Server is running on port 5000');
});
Enter fullscreen mode Exit fullscreen mode

Integrate Socket.io

Install Socket.io:

bashCopy codenpm install socket.io
Enter fullscreen mode Exit fullscreen mode

Modify your index.js to include Socket.io:

javascriptCopy code// index.js
const socketIo = require('socket.io');
const io = socketIo(server, {
  cors: {
    origin: 'http://localhost:3000', // React app domain
    methods: ['GET', 'POST'],
  },
});

io.on('connection', (socket) => {
  console.log('New client connected');

  // Handle disconnection
  socket.on('disconnect', () => {
    console.log('Client disconnected');
  });
});

// Export io for use in routes
module.exports = io;
Enter fullscreen mode Exit fullscreen mode

Connect to MongoDB

Install Mongoose:

bashCopy codenpm install mongoose
Enter fullscreen mode Exit fullscreen mode

Update index.js to connect to MongoDB:

javascriptCopy code// index.js
const mongoose = require('mongoose');

mongoose
  .connect('mongodb://localhost:27017/notifications', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => console.log('MongoDB connected'))
  .catch((err) => console.log(err));
Enter fullscreen mode Exit fullscreen mode

Create Notification Schema

Create a models directory and add a Notification.js file:

javascriptCopy code// models/Notification.js
const mongoose = require('mongoose');

const NotificationSchema = new mongoose.Schema({
  message: String,
  date: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Notification', NotificationSchema);
Enter fullscreen mode Exit fullscreen mode

API Endpoints

Create a route to handle creating notifications:

javascriptCopy code// routes/notifications.js
const express = require('express');
const router = express.Router();
const Notification = require('../models/Notification');
const io = require('../index'); // Import io instance

// Create a new notification
router.post('/', async (req, res) => {
  const { message } = req.body;
  try {
    const notification = new Notification({ message });
    await notification.save();

    // Emit the notification to all connected clients
    io.emit('notification', notification);

    res.status(201).json(notification);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Update index.js to use the route:

javascriptCopy code// index.js
const notificationRoutes = require('./routes/notifications');

app.use('/notifications', notificationRoutes);
Enter fullscreen mode Exit fullscreen mode

Setting Up the Frontend

Initialize React App

Use create-react-app to bootstrap your React application:

bashCopy codenpx create-react-app client
cd client
Enter fullscreen mode Exit fullscreen mode

Install Dependencies

Install Socket.io client:

bashCopy codenpm install socket.io-client axios
Enter fullscreen mode Exit fullscreen mode

Set Up Socket.io Client

In your App.js, set up the Socket.io client to listen for notifications:

javascriptCopy code// src/App.js
import React, { useEffect, useState } from 'react';
import socketIOClient from 'socket.io-client';
import axios from 'axios';

const ENDPOINT = 'http://localhost:5000';

function App() {
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    // Fetch existing notifications
    axios.get(`${ENDPOINT}/notifications`).then((response) => {
      setNotifications(response.data);
    });

    // Set up Socket.io client
    const socket = socketIOClient(ENDPOINT);

    socket.on('notification', (data) => {
      setNotifications((prevNotifications) => [data, ...prevNotifications]);
    });

    // Clean up the connection when the component unmounts
    return () => socket.disconnect();
  }, []);

  return (
    <div>
      <h1>Notifications</h1>
      {notifications.map((notif) => (
        <div key={notif._id}>
          <p>{notif.message}</p>
          <small>{new Date(notif.date).toLocaleString()}</small>
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Display Notifications

The above code in App.js will display the list of notifications and update the list in real-time when a new notification is received.


Testing the Notification System

To test the notification system:

  1. Start the backend server:

    bashCopy codenode index.js
    
  2. Start the React app:

    bashCopy codecd client
    npm start
    
  3. Send a notification:

    Use a tool like Postman or curl to send a POST request to the /notifications endpoint:

    bashCopy codecurl -X POST -H "Content-Type: application/json" -d '{"message": "New notification"}' http://localhost:5000/notifications
    

    Alternatively, you can create a simple form in your React app to send notifications.

  4. Observe the React app:

    The new notification should appear instantly in your React application without a page refresh.


Conclusion

You've now set up a basic real-time notification system using Express.js, MongoDB, Socket.io, and React. This system can be expanded and customized to fit more complex use cases, such as user-specific notifications, different notification types, and persistent user sessions.

Next Steps:

  • Authentication: Implement user authentication to send notifications to specific users.

  • Notification Types: Categorize notifications and add filtering options.

  • Persistent Connections: Handle reconnection logic for Socket.io in case of network issues.

  • UI Enhancements: Improve the frontend with better styling and user experience.


Resources:

💖 💪 🙅 🚩
morshedulmunna
Morshedul Munna

Posted on September 8, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related