'how can I receive notification by another user using channels in django?

actually, this is the first time I use channels but it's an easy concept to understand.

I followed a tutorial that took me to the way in which I can send the notification the real-time but there's a part that I can't see at any tutorial where they are oblivious to it.

all tutorials show how can send a notification or messages via chat when I do that for a single user after I open the new page, the page works fine. for example, if I logged in by username "test" and opened a new browser logged in by username "test" will be working fine

the problem is that: when I try to open for example an "incognito page" by google chrome to use a different user such as "new test" username that I want him to receive the notification we can consider him a target user from the sender on the main page "test".

now the data is changing in the database but I can't see that change in front of my eyes unless I reload the web page.

when I tested that out I see javascript doesn't receive any of the data in the "new test" user and I think this problem occurs because of channel_layer somehow.

any help and explanation for what is going on here?

#consumers.py

from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
import json

from .models import Notification
from django.contrib.auth.models import User


class NotificationConsumer(AsyncConsumer):
    async def websocket_connect(self, event):
        await self.send({
            'type': 'websocket.accept',
        })

        user = self.scope['user']
        notif_room = f"user_id_{user.id}"
        self.notif_room = notif_room

        await self.channel_layer.group_add(
            notif_room,
            self.channel_name
        )

    async def websocket_receive(self, event):
        serialize_data = json.loads(event['text'])
        self.comment = serialize_data['comment']
        self.user_sender = serialize_data['user_sender']

        notif_count = await self.update_notification()

        await self.channel_layer.group_send(
            self.notif_room,
            {
                "type": 'send_notif',
                'text': json.dumps({'notif_count': notif_count})
            }
        )

    async def send_notif(self, event):
        await self.send({
            'type': 'websocket.send',
            'text': event['text']
        })

    async def websocket_disconnect(self, event):
        print("Disconnect the connections")

    @database_sync_to_async
    def update_notification(self):
        comment = self.comment
        user_sender = User.objects.get(id=int(self.user_sender))

        notifs = Notification.objects.create(
            user_sender=user_sender,
            message=comment
        )
        for users in User.objects.all().exclude(username=self.scope['user'].username):
            users.rec.add(notifs)
        return Notification.objects.filter(user_receiver=self.scope['user'].id).count()

#file.html

{% extends 'base.html' %}
{% block title %} Data Show {% endblock %}

{% block body %}
    <div class="container">
        <button type="button" class="btn notification-button btn-primary">
            Notifications <span class="badge badge-light">{{ notifications.count }}</span>
        </button>
        <br><br/>
        <form id="formData" method="post">
            {% csrf_token %}
            {% if user.is_authenticated %}
            <input type="text" hidden="hidden" value="{{ user_sender.id }}" name="user">
            {% endif %}
            <input type="text" name="comment" id="comment">
            <input type="submit" value="create" />
        </form>
    </div>
    <script>
        let ws_protocol = "ws://";
        const navigation = window.location;
        let formData = document.getElementById("formData");
        let id_name = document.getElementById("id-name");
        let user = document.querySelector("input[name='user']");
        let comment = document.getElementById("comment");
        let notif_label = document.querySelector(".badge");
        let notification_button = document.querySelector(".notification-button");

        if (navigation.protocol === "https") {
            ws_protocol = "wss://";
        }

        let target = `${ws_protocol}${navigation.host}${navigation.pathname}`
        const socket = new WebSocket(target);

        socket.onopen = (e) => {
            console.log("connection accepted by javascript");
            formData.onsubmit = function (e) {
                e.preventDefault();
                try {
                    let data = {
                        "comment": comment.value,
                        "user_sender": user.value
                    }
                    socket.send(JSON.stringify(data))
                } catch (e) {
                    alert("you should login to be able to comment here");
                }
            }
        }
        socket.onmessage = (e) => {
            console.log("receive message by javascript");
            let json_data = JSON.parse(JSON.stringify(e.data))
            json_data = JSON.parse(json_data)
            notif_label.textContent = json_data.notif_count;
            console.log(json_data)
        }
        socket.onerror = (e) => {
            console.log("display error by javascript");
        }
        socket.onclose = (e) => {
            console.log("close connection by javascript");
        }

        notification_button.onclick = function() {
            notif_label.textContent = '';
        }
    </script>
{% endblock %}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source