Integrating Django WebPush with DRF and React Frontend

80 views
Skip to first unread message

cendiant analysis

unread,
Jul 17, 2024, 2:23:19 PM7/17/24
to Django REST framework

Hello everyone,

I am working on a project where I need to implement web push notifications using Django. My backend is based on Django Rest Framework (DRF), and my frontend is built with React. I am looking for a solution that does not rely on external service providers like Firebase or OneSignal.

Specifically, I would like to know:

  1. Will Django WebPush work with DRF?
  2. Are there any native Django packages that can help me connect the backend with a React frontend for web push notifications?

Any insights or recommendations would be greatly appreciated. Thank you!

azeem

unread,
Jul 31, 2024, 10:28:57 AM7/31/24
to Django REST framework
  Implementing web push notifications in a Django project using Django Rest Framework (DRF) and React without relying on external service providers can be achieved using the django-webpush package. Here’s a detailed guide to help you set it up.

   Step 1: Install Required Packages

First, install the django-webpush package.

Step 2: Configure Django Settings

Add webpush to your INSTALLED_APPS in settings.p

Step 3: Add URLs and Views

Add the necessary URLs for subscribing and sending notifications in urls.py.

from django.urls import path
from webpush.views import save_info

urlpatterns = [
    # Other URLs
    path('webpush/save_information/', save_info, name='save_webpush_info'),
]


Step 4:
  Create a view to handle sending notifications. You can create a new file views.py or add to an existing one.

from django.shortcuts import get_object_or_404
from webpush import send_user_notification
from django.contrib.auth.models import User
from django.http import JsonResponse

def send_push_notification(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    payload = {"head": "Welcome!", "body": "Hello World!", "icon": "path/to/icon.png", "url": "https://example.com"}
    send_user_notification(user=user, payload=payload, ttl=1000)
    return JsonResponse({"status": "Notification sent"})


Step 5:
 Create Push Manager on the Frontend

In your React application, you need to add service worker logic to handle push notifications.

  1. Create a Service Worker (service-worker.js):
self.addEventListener('push', function(event) {
    const data = event.data.json();
    const options = {
        body: data.body,
        icon: data.icon,
        data: { url: data.url },
    };
    event.waitUntil(
        self.registration.showNotification(data.head, options)
    );
});

self.addEventListener('notificationclick', function(event) {
    event.notification.close();
    event.waitUntil(
        clients.openWindow(event.notification.data.url)
    );
});

  Register Service Worker and Subscribe to Push Notifications in React:  
  // public/service-worker.js must be at the root level of your public directory
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker.register('/service-worker.js')
        .then(registration => {
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
            return registration.pushManager.getSubscription()
            .then(subscription => {
                if (subscription) {
                    return subscription;
                }
                const vapidPublicKey = '<Your VAPID Public Key>';
                const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
                return registration.pushManager.subscribe({
                    userVisibleOnly: true,
                    applicationServerKey: convertedVapidKey,
                });
            });
        })
        .then(subscription => {
            fetch('/webpush/save_information/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    subscription: subscription,
                    user: user_id,  // Pass the user id from your frontend
                }),
            });
        })
        .catch(error => {
            console.log('ServiceWorker registration failed: ', error);
        });
    });
}

function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/-/g, '+')
        .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
Reply all
Reply to author
Forward
0 new messages