Skip to main content

Command Palette

Search for a command to run...

Leveraging Asynchronous Messaging for Real-Time Notifications in Web Applications

Published
5 min read
Leveraging Asynchronous Messaging for Real-Time Notifications in Web Applications

In the fast-paced world of web development, providing real-time updates and notifications to users is essential for enhancing user engagement and experience. One effective way to achieve this is by implementing asynchronous messaging, where changes trigger notifications pushed to clients' devices instantly. In this article, we'll explore how to set up and implement asynchronous messaging using Flask or Django, Firebase Cloud Messaging (FCM), and RabbitMQ, enabling seamless communication between server and client.

Workflow of the Application:

  1. Change Detection: The application detects a relevant change, such as a new order being placed or an update to an existing order.

  2. Notification Generation: Upon detecting the change, the application generates a notification payload containing relevant information, such as the order details or the nature of the change.

  3. Message Queueing: The notification payload is then queued in RabbitMQ, awaiting processing and delivery to clients.

  4. Firebase Cloud Messaging (FCM): A background service running on the server consumes messages from the RabbitMQ queue and sends them to FCM for distribution to clients' devices.

  5. Client-Side Notification Handling: Clients' devices receive the notifications via FCM and display them to users in real-time.

Application architecture:

Think of messages as little notes that need to be delivered from one friend to another. Sometimes, there are lots of messages and they all need to get to the right friend as quickly as possible.

That's where a message broker comes in. It's like a special helper that helps organize and deliver these messages efficiently. Instead of your friends running all over the place trying to find each other to deliver their notes, they can just give their notes to the message broker, and it takes care of making sure each note gets to the right friend.

The message broker knows who needs to receive each message, so it sorts them out and sends them to the right place.

Setting Up the Environment:

  1. Flask/Django Setup: Begin by setting up a Flask or Django application to handle web requests and business logic. Install necessary dependencies and configure routes to handle change detection and notification generation.

  2. RabbitMQ Installation: Install RabbitMQ on your server to act as the message broker. Configure queues and exchanges as needed for message routing.

  3. Firebase Integration: Set up Firebase Cloud Messaging (FCM) for sending push notifications to clients' devices. Obtain the necessary credentials and configure your server to authenticate with FCM.

Implementation:

A. Flask/Django Implementation:

def publish_to_rabbitmq(payload):
    # Logic to publish payload to RabbitMQ queue
    # Establish connection to RabbitMQ server
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    channel = connection.channel()

    # Declare a queue
    channel.queue_declare(queue='notifications')

    # Publish the payload to the queue
    channel.basic_publish(exchange='',
                          routing_key='notifications',
                          body=payload)

    # Close the connection
    connection.close()

@app.route('/detect_change', methods=['POST'])
def detect_change():
    # Logic to detect change
    # Generate notification payload
    payload = {
        'title': 'New Order Placed',
        'body': 'An order has been placed. Check your dashboard for details.'
    }
    # Publish payload to RabbitMQ queue
    publish_to_rabbitmq(payload)
    return 'Change detected and notification sent!'

In this logic:

  1. We import the pika library, which is a Python client for RabbitMQ.

  2. We define the publish_to_rabbitmq function that takes a payload as input.

  3. Inside the function, we establish a connection to the RabbitMQ server running on localhost.

  4. We create a channel through which we'll communicate with RabbitMQ.

  5. We declare a queue named 'notifications' using queue_declare method. This ensures that the queue exists before we attempt to publish messages to it.

  6. We use the basic_publish method to publish the payload to the 'notifications' queue. The exchange parameter is left empty as we're using the default exchange. The routing_key specifies the queue to which the message will be routed, and body contains the payload.

  7. Finally, we close the connection to RabbitMQ.

With this logic in place, whenever you call publish_to_rabbitmq(payload), the payload will be published to the 'notifications' queue in RabbitMQ. From there, any consumers listening to that queue will be able to receive and process the messages.

B. FCM Integration:

# FCM Integration Example
from pyfcm import FCMNotification

def send_to_fcm(payload):
    push_service = FCMNotification(api_key="YOUR_FCM_API_KEY")
    registration_id = "CLIENT_DEVICE_TOKEN"
    push_service.notify_single_device(registration_id=registration_id, data_message=payload)

If you have multiple clients and you don't know their device tokens, you'll need to handle device registration and store the device tokens associated with each client.

Here's how you can modify the method to send notifications to multiple devices:

from pyfcm import FCMNotification

# Initialize FCM service with your API key
push_service = FCMNotification(api_key="YOUR_FCM_API_KEY")

def send_to_fcm(payload, registration_ids):
    # Send notification to multiple devices using their registration IDs
    push_service.notify_multiple_devices(registration_ids=registration_ids, data_message=payload)

In the provided method send_to_fcm(payload), the registration_id parameter represents the unique device token of a single device. If you have multiple clients and you don't know their device tokens, you'll need to handle device registration and store the device tokens associated with each client.

Here's how you can modify the method to send notifications to multiple devices:

from pyfcm import FCMNotification

# Initialize FCM service with your API key
push_service = FCMNotification(api_key="YOUR_FCM_API_KEY")

def send_to_fcm(payload, registration_ids):
    # Send notification to multiple devices using their registration IDs
    push_service.notify_multiple_devices(registration_ids=registration_ids, data_message=payload)

With this modification:

  • registration_ids should be a list containing the device tokens of all the clients you want to send the notification to.

  • The notify_multiple_devices method of FCMNotification allows you to send notifications to multiple devices simultaneously.

Conclusion:

By integrating Flask or Django with RabbitMQ and Firebase Cloud Messaging, you can create a robust system for asynchronous messaging and real-time notifications in your web applications. This setup ensures efficient communication between server and client, enabling seamless delivery of notifications based on changes in the application state. With the provided implementation examples, you can easily set up and configure the components to enhance user engagement and provide a dynamic user experience.