Скажите, почему при доставке сообщений через WebSockets они в кракозябрах?

Кракозябры наблюдаю только когда от сервера (из БД и скрипт севера) данные отправляются на клиент (браузер). Запускаю скрипты и сервера и клиента в WebStorm. Кодировка клиента 1251, а кодировка файла сервера UTF-8. Но когда обоих делаю одну и ту же кодировку, то все равнов чате кракозябры, только еще и по странице клиентского чата на сайте тоже иероглифы появляются. Вот код сервера:

const WebSocket = require('ws');
const admin = require("firebase-admin");

// Инициализация Firebase Admin SDK
const serviceAccount = require("C:/Users/Youra2/WebstormProjects/untitled2/serviceAccountKey.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://newchat-8d312-default-rtdb.firebaseio.com"
});

const db = admin.database();
const usersRef = db.ref('users');
const UsersRef_Android = db.ref('Users');
const domainsRef = db.ref('Domains'); // Ссылка на коллекцию доменов
const chatsRef = db.ref('Chats'); // Ссылка на корневую коллекцию Chats

const wss = new WebSocket.Server({
    port: 8081
});

wss.on('connection', ws => {
    console.log('Client connected');

    ws.on('message', async (message) => {
        try {
            const data = JSON.parse(message);
            //data.messageText = undefined;

            if (data.type === 'connection') {
                const domain = data.domain;
                const userId = data.userId;
                //const messageText = data.messageText;
                const sender = data.sender;

                console.log(`connection Получено сообщение domain : ${domain}`);
                console.log(`connection Получено сообщение userId : ${userId}`);
                //   console.log(`Получено сообщение messageText: ${messageText}`);
                console.log(`connection Получено сообщение sender: ${sender}`);

                // Сохраняем данные пользователя в Firebase
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString()
                });

                console.log(`connection User ${userId} from domain ${domain} saved to Firebase`);

                // Проверка принадлежности домена к АДМИНУ этого ДОМЕНА
                const domainSnapshot = await domainsRef.child(domain).once('value');
                const domainData = domainSnapshot.val();
                const defaultUserAdmin = 'Nqt1vRYDMwVaAdtSUVqVCtXlxq03';

                let userAdmin;
                if (domainData && domainData.UserAdmin) {
                    userAdmin = domainData.UserAdmin;
                    console.log(`connection Owner of domain ${domain} is UserAdmin: ${userAdmin}`);
                } else {
                    userAdmin = defaultUserAdmin; // Значение по умолчанию
                    await domainsRef.child(domain).set({ UserAdmin: userAdmin });
                    console.log(` connection No owner found for domain ${domain}, setting UserAdmin to default value ${userAdmin}`);
                }




                // Сохраняем или находим идентификатор чата для пользователя
                const chatSnapshot = await chatsRef.orderByChild('user1').equalTo(userId).once('value');
                let chatId;
                if (chatSnapshot.exists()) {
                    // Если чат уже существует, получаем его ID
                    chatId = Object.keys(chatSnapshot.val())[0];
                    console.log(` connection Chat found for user ${userId}: ${chatId}`);
                } else {
                    // Если чата нет, создаем новый
                    chatId = chatsRef.push().key;

                    // Записываем данные чата
                    await chatsRef.child(chatId).set({
                        user1: userId,
                        user2: userAdmin // Устанавливаем значение владельца домена
                    });
                    console.log(` connection New chat created for user ${userId}: ${chatId}`);
                }

                //для USER ветки ДОБАВИМ ЧАТ НОВЫЙ ЮЗЕРУ ЧЕРЕЗ ЗАПЯТУЮ
                // Сначала создаём ссылку на узел пользователя
                // Сначала создаем ссылку на узел пользователя
                //  const userRef = UsersRef_Android.child(userAdmin); // или другой подходящий путь
                console.log(`!!!!!!!!!!!!!!! chatId: ${chatId},  ЭТО КОННЕКТЕД ТИП, userAdmin: ${userAdmin}`);
                const UsersRef_Android2 = UsersRef_Android.child(userAdmin);

                // Обновляем значение в корневой папке Users
                try {
                    // Используем once для получения текущих значений подключения
                    const userSnapshot = await UsersRef_Android2.once('value');

                    if (userSnapshot.exists()) { //Проверяет, существует ли узел данных, к которому мы обращаемся. Если он существует, возвращаемое значение будет истинным.
                        let currentChats = userSnapshot.val().chats || ''; // Получаем текущее значение chats в БД для андроид
                        if (currentChats) {
                            currentChats += ','; // Если уже есть значение, добавляем запятую
                        }
                        currentChats += chatId; // Добавляем новое значение chatId

                        // Обновляем значение в Firebase
                        await UsersRef_Android2.child('chats').set(currentChats);
                        console.log(`!!!!!!!!!!! ОБНОВЛЕН (ДОБАВЛЕН) ЧАТ ДЛЯ ЮЗЕРА Updated chats for user-ADMIN: ${userAdmin}: НАЗВАНЕ ЧАТОВ: ${currentChats}`);
                    } else {
                        // Если нет текущих значений, создать chats с chatId
                        await userRef.child('chats').set(chatId);
                        console.log(`!!! СОЗДАН (ВСТАВЛЕН) ЧАТ ДЛЯ ЮЗЕР_АДМИН Created new chats for user ${userAdmin}: ЧАТ ИД: ${chatId}`);
                    }
                } catch (error) {
                    console.error('Error updating chats', error);
                }


                ///---------------------------
                //ДОБАВЛЯЕМ ВРЕМЕННОГО ПОЛЬЗОВАТЕЛЯ сайта В ВЕТВЬ USERS
                // Создаем уникальное имя пользователя
                function generateUsername(domain) {
                    const randomDigits = Math.floor(100 + Math.random() * 900); // Генерируем три случайные цифры
                    const today = new Date();
                    const formattedDate = today.toLocaleDateString('ru-RU'); // Форматируем текущую дату как ДД.ММ.ГГ

                    // Собираем имя пользователя
                    return `${domain}${randomDigits}${formattedDate}`;
                }

                // Создаем имя пользователя
                const username = generateUsername(domain);

                // Получение ссылки на Users
                const UsersRef = UsersRef_Android;

                // Создаем суб-ветвь с userId и добавляем поле username
                UsersRef.child(userId).set({
                    username: username
                })
                    .then(() => {
                        console.log(`В ВЕТВЬ USERS (для андроида) ДОБАВЛЕН НОВЫЙ User with ID ${userId} created with username: ${username}`);
                    })
                    .catch((error) => {
                        console.error('В ВЕТВЬ USERS (для андроида) НЕ !! ДОБАВЛЕН Error creating user:', error);
                    });



                //----------------------

                //my
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString()
                });

                // Сохранение чата и отправка сообщения
                // const messageText = data.messageText;

                // const sender = data.sender;
                const timestamp = new Date().toISOString(); // Используйте текущую дату

                // Проверьте все значения
                console.log(`connection Preparing to save message from sender=: ${sender}, text messageText= ЭТО КОННЕКТЕД ТИП, chatId: ${chatId}`);

                // Сохраняем сообщение в подкатегории messages
                await chatsRef.child(chatId).child('messages').push().set({
                    date: timestamp,
                    ownerId: sender,
                    text: "test new create chat"
                });

                console.log(` connection Message saved to Firebase`);



                //NEW MY
                // Подписка на новые сообщения в чате
                chatsRef.child(chatId).child('messages').on('child_added', (snapshot) => {
                    const messageData = snapshot.val();
                    const messageSender = messageData.sender;

                    // Отправляем сообщение клиенту через WebSocket

                    if (ws.readyState === WebSocket.OPEN) {
                        ws.send(JSON.stringify({
                            type: 'Message',
                            message: messageData,
                            sender: "user"
                        }));
                    }
                    console.log(`ПРИШЛО НОВОЕ СООБЩЕНИЕ В  БД : $ ${messageData}`);
                });

                //-----------------------
                // Отправляем сообщение всем подключенным клиентам
                wss.clients.forEach(client => {
                    if (client.readyState === WebSocket.OPEN) {
                        client.send(JSON.stringify(data));
                    }
                });

            }
            else if (data.type === 'message') {
                // Обработка сообщений
                const messageText = data.text; // предположим, что именно это теперь ваше сообщение
                const sender = data.sender;
                const domain = data.domain;
                const userId = data.userId;
                //console.log(`Preparing to save message from sender=: ${sender}, text messageText=: ${messageText}, chatId: ${chatId}`);
                console.log(` message Preparing to save message from sender=: ${sender}, text messageText=: ${messageText},`);
                if (!sender || !messageText) {
                    console.error('message Sender or message text is undefined. Message data:', data);
                    return; // Отменяем дальнейшие действия, если данные некорректные
                }

                console.log(` message Preparing to save message from: ${sender}, text: ${messageText}`);



                // !!!!  Здесь добавьте логику к сохранению сообщения в базе данных !!!!!
                // const timestamp = new Date().toISOString();
                // Проверка принадлежности домена
                const domainSnapshot = await domainsRef.child(domain).once('value');
                const domainData = domainSnapshot.val();
                const defaultUserAdmin = 'Nqt1vRYDMwVaAdtSUVqVCtXlxq03';

                let userAdmin;
                if (domainData && domainData.UserAdmin) {
                    userAdmin = domainData.UserAdmin;
                    console.log(`connection Owner of domain ${domain} is UserAdmin: ${userAdmin}`);
                } else {
                    userAdmin = defaultUserAdmin; // Значение по умолчанию
                    await domainsRef.child(domain).set({ UserAdmin: userAdmin });
                    console.log(` connection No owner found for domain ${domain}, setting UserAdmin to default value ${userAdmin}`);
                }

                // Сохраняем или находим идентификатор чата для пользователя
                const chatSnapshot = await chatsRef.orderByChild('user1').equalTo(userId).once('value');
                let chatId;
                if (chatSnapshot.exists()) {
                    // Если чат уже существует, получаем его ID
                    chatId = Object.keys(chatSnapshot.val())[0];
                    console.log(` connection Chat found for user ${userId}: ${chatId}`);
                } else {
                    // Если чата нет, создаем новый
                    chatId = chatsRef.push().key;

                    // Записываем данные чата
                    await chatsRef.child(chatId).set({
                        user1: userId,
                        user2: userAdmin // Устанавливаем значение владельца домена
                    });
                    console.log(` connection New chat created for user ${userId}: ${chatId}`);
                }



                //my
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString(),
                    text: messageText
                });

                // Сохранение чата и отправка сообщения
                // const messageText = data.messageText;

                // const sender = data.sender;
                const timestamp = new Date().toISOString(); // Используйте текущую дату

                // Проверьте все значения
                console.log(`connection Preparing to save message from sender=: ${sender}, text messageText= ЭТО КОННЕКТЕД ТИП, chatId: ${chatId}`);

                // Сохраняем сообщение в подкатегории messages
                await chatsRef.child(chatId).child('messages').push().set({
                    date: timestamp,
                    ownerId: sender,
                    text: messageText,
                    domain: domain
                });

                console.log(` connection Message saved to Firebase`);

                // Сохраните сообщение в Firebase здесь...

                //---------------------------------------------------------------------------
                //MY NEW


            }

        } catch (error) {
            console.error('Error processing message:', error);
        }
    });

    ws.on('close', () => {
        console.log('Client disconnected');
    });

    ws.on('error', error => {
        console.error('WebSocket error:', error);
    });
});

console.log('WebSocket server started on port 8081');

А вот код клиента на сайте:

<!DOCTYPE html>
<html>

<head>
    <title>Чат</title>
    <style>
        /* Стили для чата в правом нижнем углу */
        #chat-widget {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 350px;
            border: 1px solid #ccc;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
            /* Тень для выделения */
            background-color: white;
            /* Белый фон */
        }

        #chat-header {
            background-color: #007bff;
            /* Более яркий цвет для заголовка */
            color: white;
            padding: 10px;
            text-align: center;
            cursor: pointer;
            font-weight: bold;
        }

        #chat-body {
            height: 300px;
            overflow-y: scroll;
            padding: 10px;
            display: flex;
            /* Используем Flexbox */
            flex-direction: column;
            /* Сообщения сверху вниз */
        }

        #chat-input-area {
            padding: 10px;
            border-top: 1px solid #eee;
            display: flex;
        }

        #message-input {
            flex-grow: 1;
            padding: 5px;
            border: 1px solid #ddd;
            border-radius: 3px;
        }

        #send-button {
            padding: 5px 10px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            margin-left: 5px;
        }

        .message {
            padding: 8px;
            border-radius: 5px;
            margin-bottom: 5px;
            word-break: break-word;
            /* Предотвращает выход длинных слов за границы */
        }

        .user-message {
            background-color: #e2f7cb;
            /* Светло-зеленый для сообщений пользователя */
            align-self: flex-end;
            /* Сообщения пользователя справа */
        }

        .operator-message {
            background-color: #f0f0f0;
            /* Светло-серый для сообщений оператора */
            align-self: flex-start;
            /* Сообщения оператора слева */
        }

        .system-message {
            color: gray;
            font-style: italic;
            text-align: center;
        }

        /* Скрываем тело чата при сворачивании */
        #chat-widget.collapsed #chat-body,
        #chat-widget.collapsed #chat-input-area {
            display: none;
        }

        /* Изменяем вид заголовка при свернутом состоянии */
        #chat-widget.collapsed #chat-header {
            border-bottom: none;
            border-radius: 5px;
        }

        /* Добавляем стили для отображения времени сообщения */
        .message-time {
            font-size: 0.7em;
            color: #777;
            margin-top: 2px;
        }

        .message-time.user-time {
            text-align: right;
        }

        .message-time.operator-time {
            text-align: left;
        }
    </style>
</head>

<body>

<div id="chat-widget">
    <div id="chat-header">Чат</div>
    <div id="chat-body"></div>
    <div id="chat-input-area">
        <input type="text" id="message-input" placeholder="Введите сообщение">
        <button id="send-button">Отправить</button>
    </div>
</div>

<script src="https://www.gstatic.com/firebasejs/9.6.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.1/firebase-database-compat.js"></script>

<script>
    // Firebase configuration (Replace with your actual configuration)
    const firebaseConfig = {
        apiKey: "AIzaSyDGSiY7O6krTIZj0A-iRvgaXsiN2VaJQ84",
        authDomain: "newchat-8d312.firebaseapp.com",
        databaseURL: "https://newchat-8d312-default-rtdb.firebaseio.com",
        projectId: "newchat-8d312",
        storageBucket: "newchat-8d312.firebasestorage.app",
        messagingSenderId: "831027870202",
        appId: "1:831027870202:web:571c1b0e06cd4b51d1cc43"

    };

    // Initialize Firebase
    const app = firebase.initializeApp(firebaseConfig);
    const database = firebase.database();

    const chatWidget = document.getElementById('chat-widget');
    const chatHeader = document.getElementById('chat-header');
    const chatBody = document.getElementById('chat-body');
    const messageInput = document.getElementById('message-input');
    const sendButton = document.getElementById('send-button');
    const chatMessagesRef = database.ref('messages'); // Reference to your messages in Firebase

    // WebSocket configuration
    const websocketUrl = 'ws://localhost:8081'; // Replace with your WebSocket server URL
    let websocket;
    let isConnectedToWebSocket = false;

    // Generate a unique user ID
    function generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random() * 16 | 0,
                v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    const userId = generateUUID();
    const domainName = window.location.hostname; // Get the domain name

    function connectWebSocket() {
        websocket = new WebSocket(websocketUrl);

        websocket.onopen = () => {
            console.log('Connected to WebSocket server');
            isConnectedToWebSocket = true;

            // Send domain and user ID upon connection
            //let messageText = messageData.text;
            let sender = "333";
            const connectionData = {
                type: 'connection',
                domain: domainName,
                userId: userId,
                 sender: sender // Получаем имя отправителя
            };

            websocket.send(JSON.stringify(connectionData));
        };

        websocket.onmessage = (event) => {
            const messageData = JSON.parse(event.data);
            console.log(' var messageData = ');
            console.log(messageData);
            console.log('event.data = ');
            console.log(event.data);

            if (messageData.type === 'Message') {
                const messageText = messageData.text;
                const sender = messageData.sender; // Получаем имя отправителя
                const timestamp = messageData.timestamp;
                console.log('messageData.type = ');
                console.log(messageData.type);
                console.log('messageText = ');
                console.log(messageText);
                console.log('sender = ');
                console.log(sender);

                // Отображаем сообщение в чате
                displayMessage(messageText, sender, timestamp);
            } else if (messageData.type === 'system') {
                appendSystemMessage(messageData.text);
            }
        };


        websocket.onclose = () => {
            console.log('Disconnected from WebSocket server');
            isConnectedToWebSocket = false;
        };

        websocket.onerror = (error) => {
            console.error('WebSocket error:', error);
        };
    }

    function sendMessage(messageText) {
        if (!isConnectedToWebSocket) {
            console.log('Not connected to WebSocket server. Message not sent.');
            appendSystemMessage('Не удалось отправить сообщение. Нет соединения с сервером.');
            return;
        }

        const messageData = {
            type: 'message',
            text: messageText,
            sender: userId,
            timestamp: new Date().toISOString(),
            domain: domainName,
            userId: userId
        };

        websocket.send(JSON.stringify(messageData));
        displayMessage(messageText, 'user', messageData.timestamp); // Display own message
        messageInput.value = ''; // Clear input field
    }







    function displayMessage(messageText, sender, timestamp) {
        const messageElement = document.createElement('div');
        messageElement.classList.add('message');

        if (sender === 'user') {
            messageElement.classList.add('user-message');
        } else if (sender === 'operator') {
            messageElement.classList.add('operator-message');
        } else {
            // Сообщение от системы (например, сообщение о подключении/отключении)
            messageElement.classList.add('system-message');
            messageElement.textContent = messageText;
            chatBody.appendChild(messageElement); // Добавляем системное сообщение в чат
            chatBody.scrollTop = chatBody.scrollHeight; // Прокручиваем вниз
            return; // Выходим из функции, чтобы не добавить также и время
        }

        messageElement.textContent = messageText;

        // Добавляем время сообщения
        const timeElement = document.createElement('div');
        timeElement.classList.add('message-time');
        if (sender === 'user') {
            timeElement.classList.add('user-time');
        } else {
            timeElement.classList.add('operator-time');
        }
        const date = new Date(timestamp);
        const hours = date.getHours().toString().padStart(2, '0');
        const minutes = date.getMinutes().toString().padStart(2, '0');
        timeElement.textContent = `${hours}:${minutes}`;
        messageElement.appendChild(timeElement);

        chatBody.appendChild(messageElement);
        chatBody.scrollTop = chatBody.scrollHeight;
    }

    function appendSystemMessage(message) {
        const systemMessage = document.createElement('div');
        systemMessage.classList.add('system-message');
        systemMessage.textContent = message;
        chatBody.appendChild(systemMessage);
        chatBody.scrollTop = chatBody.scrollHeight;
    }

    // Event listeners
    sendButton.addEventListener('click', () => {
        const messageText = messageInput.value.trim();
        if (messageText !== '') {
            sendMessage(messageText);
        }
    });

    messageInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            event.preventDefault();
            const messageText = messageInput.value.trim();
            if (messageText !== '') {
                sendMessage(messageText);
            }
        }
    });

    chatHeader.addEventListener('click', () => {
        chatWidget.classList.toggle('collapsed');
    });

    // Initialize WebSocket connection
    connectWebSocket();
</script>

</body>

</html>

Даже когда цифры воодишь тоже кракозябры, причем одна и та же крокозябра: введите сюда описание изображения Скажите, как сделать чтобы было корректное отображение присланного текста по WebSockets в чате? (в БД данные корретны).

Обновление: Я добавил максимум логгирования и оказалось что приходит с сервера до клиента нормально сообщение, но почесму то на клиенте не все данные удается спарсить! Вот лог хтмл файла:

введите сюда описание изображения

Почему messageData.type удается спарсить, а messageData.text не установлена переменная ? при этом все данные получены клиентом в event.data = index2_test.html:202{"type":"Message","message":{"date":"2025-02-18T10:04:53.302Z","ownerId":"333","text":"test new create chat"},"sender":"user"}


Ответы (1 шт):

Автор решения: Youra

Ответ был найден. Ошибка была в коде сервера. Просто не задал значения перемнным. Поэтому такую ошибдку получал. Вот верный код:

const WebSocket = require('ws');
const admin = require("firebase-admin");

// Инициализация Firebase Admin SDK
const serviceAccount = require("C:/Users/Youra2/WebstormProjects/untitled2/serviceAccountKey.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://newchat-8d312-default-rtdb.firebaseio.com"
});

const db = admin.database();
const usersRef = db.ref('users');
const UsersRef_Android = db.ref('Users');
const domainsRef = db.ref('Domains'); // Ссылка на коллекцию доменов
const chatsRef = db.ref('Chats'); // Ссылка на корневую коллекцию Chats

const wss = new WebSocket.Server({
    port: 8081
});

wss.on('connection', ws => {
    console.log('Client connected');

    ws.on('message', async (message) => {
        let token2;
        try {
            const data = JSON.parse(message);
            //data.messageText = undefined;

            if (data.type === 'connection') {
                const domain = data.domain;
                const userId = data.userId;
                //const messageText = data.messageText;
                const sender = data.sender;

                console.log(`connection Получено сообщение domain : ${domain}`);
                console.log(`connection Получено сообщение userId : ${userId}`);
                //   console.log(`Получено сообщение messageText: ${messageText}`);
                console.log(`connection Получено сообщение sender: ${sender}`);

                // Сохраняем данные пользователя в Firebase
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString()
                });

                console.log(`connection User ${userId} from domain ${domain} saved to Firebase`);

                // Проверка принадлежности домена к АДМИНУ этого ДОМЕНА
                const domainSnapshot = await domainsRef.child(domain).once('value');
                const domainData = domainSnapshot.val();
                const defaultUserAdmin = 'Nqt1vRYDMwVaAdtSUVqVCtXlxq03';

                let userAdmin;
                if (domainData && domainData.UserAdmin) {
                    userAdmin = domainData.UserAdmin;
                    console.log(`connection Owner of domain ${domain} is UserAdmin: ${userAdmin}`);
                } else {
                    userAdmin = defaultUserAdmin; // Значение по умолчанию
                    await domainsRef.child(domain).set({UserAdmin: userAdmin});
                    console.log(` connection No owner found for domain ${domain}, setting UserAdmin to default value ${userAdmin}`);
                }


                //ПОЛУЧАЕМ FCM ТОКЕН
                function getTokenForUser(uid) {
                    const userRef = db.ref(`Users/${uid}/token`); // Ссылка на поле "token" конкретного пользователя

                    return userRef.get()  // Используйте .get() для однократного чтения данных (обещание)
                        .then((snapshot) => {
                            if (snapshot.exists()) {
                                return snapshot.val(); // Возвращает значение "token"
                            } else {
                                console.log("No data available");
                                return null; // Или другое значение по умолчанию, если токен не найден
                            }
                        })
                        .catch((error) => {
                            console.error("Error getting token:", error);
                            return null; // Или другое значение по умолчанию при ошибке
                        });
                }

                // ПОЛУЧАЕМ ТОКЕН АДМИНА САЙТА:
                // const userId = "ваш_uid"; // Замените на фактический UID пользователя
                getTokenForUser(userAdmin)
                    .then((token) => {
                        if (token) {
                            console.log("=========Token для пользователя", userAdmin, ":", token);


                            // Здесь можно использовать полученный токен
                        } else {
                            console.log("==========Не удалось получить токен для пользователя", userAdmin);
                        }
                    });
                //token2 = getTokenForUser(userAdmin);
               let  token2 = "f33bvCEjQt2TIj_rIAuQ5D:APA91bE0I99dcYnz_6NsyglJCgzlaSwljDpxtVpE5zOYWEI8X7CjYAYpIfYC_S4-NGmVMQz_VZQLadws-CSEGn7s2gD0RNhwro_HOlwn5h2Q_NjFUMqyh9I";
                //console.log("======================================Token2 для пользователя", userAdmin, ":", token2);
                //===========ОТПРАВЛЯЕМ ПУШ АДМИНКУ САЙТА============================================================================
                const data2 = {
                    device_token: token2,
                    notification_title: 'YOUрпр_TITLE',
                    notification_body: 'YOUR_NOпрпрATION_BODY'
                };

                fetch('https://spektr-ekb.ru/test.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(data2)
                })
                    .then(response => {
                        console.log(response); // Логирование ответа сервера
                        return response.json();
                    })
                    .then(data2 => console.log(data2))
                    .catch(error => console.error('Error:', error));
             //   console.log(response.json());





                // Сохраняем или находим идентификатор чата для пользователя
                const chatSnapshot = await chatsRef.orderByChild('user1').equalTo(userId).once('value');
                let chatId;
                if (chatSnapshot.exists()) {
                    // Если чат уже существует, получаем его ID
                    chatId = Object.keys(chatSnapshot.val())[0];
                    console.log(` connection Chat found for user ${userId}: ${chatId}`);
                } else {
                    // Если чата нет, создаем новый
                    chatId = chatsRef.push().key;

                    // Записываем данные чата
                    await chatsRef.child(chatId).set({
                        user1: userId,
                        user2: userAdmin // Устанавливаем значение владельца домена
                    });
                    console.log(` connection New chat created for user ${userId}: ${chatId}`);
                }

                //для USER ветки ДОБАВИМ ЧАТ НОВЫЙ ЮЗЕРУ ЧЕРЕЗ ЗАПЯТУЮ
                // Сначала создаём ссылку на узел пользователя
                // Сначала создаем ссылку на узел пользователя
                //  const userRef = UsersRef_Android.child(userAdmin); // или другой подходящий путь
                console.log(`!!!!!!!!!!!!!!! chatId: ${chatId},  ЭТО КОННЕКТЕД ТИП, userAdmin: ${userAdmin}`);
                const UsersRef_Android2 = UsersRef_Android.child(userAdmin);

                // Обновляем значение в корневой папке Users
                try {
                    // Используем once для получения текущих значений подключения
                    const userSnapshot = await UsersRef_Android2.once('value');

                    if (userSnapshot.exists()) { //Проверяет, существует ли узел данных, к которому мы обращаемся. Если он существует, возвращаемое значение будет истинным.
                        let currentChats = userSnapshot.val().chats || ''; // Получаем текущее значение chats в БД для андроид
                        if (currentChats) {
                            currentChats += ','; // Если уже есть значение, добавляем запятую
                        }
                        currentChats += chatId; // Добавляем новое значение chatId

                        // Обновляем значение в Firebase
                        await UsersRef_Android2.child('chats').set(currentChats);

                        console.log(`!!!!!!!!!!! ОБНОВЛЕН (ДОБАВЛЕН) ЧАТ ДЛЯ ЮЗЕРА Updated chats for user-ADMIN: ${userAdmin}: НАЗВАНЕ ЧАТОВ: ${currentChats}`);
                        //НАДО СЮДА ДОБАВИТЬ получения ИМЕНИ ПОЛЬЗОВАТЕЛЯ НИК НЕЙМА
                    } else {
                        // Если нет текущих значений, создать chats с chatId
                        await userRef.child('chats').set(chatId);
                        console.log(`!!! СОЗДАН (ВСТАВЛЕН) ЧАТ ДЛЯ ЮЗЕР_АДМИН Created new chats for user ${userAdmin}: ЧАТ ИД: ${chatId}`);
                    }
                } catch (error) {
                    console.error('Error updating chats', error);
                }


                ///---------------------------
                //ДОБАВЛЯЕМ ВРЕМЕННОГО ПОЛЬЗОВАТЕЛЯ сайта В ВЕТВЬ USERS
                // Создаем уникальное имя пользователя
                function generateUsername(domain) {
                    const randomDigits = Math.floor(100 + Math.random() * 900); // Генерируем три случайные цифры
                    const today = new Date();
                    const formattedDate = today.toLocaleDateString('ru-RU'); // Форматируем текущую дату как ДД.ММ.ГГ

                    // Собираем имя пользователя
                    return `${domain}${randomDigits}${formattedDate}`;
                }

                // Создаем имя пользователя
                const username = generateUsername(domain);

                // Получение ссылки на Users
                const UsersRef = UsersRef_Android;

                // Создаем суб-ветвь с userId и добавляем поле username
                UsersRef.child(userId).set({
                    username: username
                })
                    .then(() => {
                        console.log(`В ВЕТВЬ USERS (для андроида) ДОБАВЛЕН НОВЫЙ User with ID ${userId} created with username: ${username}`);
                    })
                    .catch((error) => {
                        console.error('В ВЕТВЬ USERS (для андроида) НЕ !! ДОБАВЛЕН Error creating user:', error);
                    });


                //----------------------

                //my
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString()
                });

                // Сохранение чата и отправка сообщения
                // const messageText = data.messageText;

                // const sender = data.sender;
                const timestamp = new Date().toISOString(); // Используйте текущую дату

                // Проверьте все значения
                console.log(`connection Preparing to save message from sender=: ${sender}, text messageText= ЭТО КОННЕКТЕД ТИП, chatId: ${chatId}`);

                // Сохраняем сообщение в подкатегории messages
                await chatsRef.child(chatId).child('messages').push().set({
                    date: timestamp,
                    ownerId: sender,
                    text: "test new create chat"
                });

                console.log(` connection Message saved to Firebase`);


                //NEW MY
                // Подписка на новые сообщения в чате
                chatsRef.child(chatId).child('messages').on('child_added', (snapshot) => {
                    const messageData = snapshot.val();
                    const messageSender = messageData.sender;
                    const text = messageData.text;

                    // Отправляем сообщение клиенту через WebSocket

                    if (ws.readyState === WebSocket.OPEN) {
                        ws.send(JSON.stringify({
                            type: 'Message',
                            message: messageData,
                            sender: "user",
                            text: text
                        }));
                    }
                    console.log(`ПРИШЛО НОВОЕ СООБЩЕНИЕ В  БД : $ ${messageData}`);
                });

                //-----------------------
                // Отправляем сообщение всем подключенным клиентам
                wss.clients.forEach(client => {
                    if (client.readyState === WebSocket.OPEN) {
                        client.send(JSON.stringify(data));
                    }
                });

            } else if (data.type === 'message') {
                // Обработка сообщений
                const messageText = data.text; // предположим, что именно это теперь ваше сообщение
                const sender = data.sender;
                const domain = data.domain;
                const userId = data.userId;
                //console.log(`Preparing to save message from sender=: ${sender}, text messageText=: ${messageText}, chatId: ${chatId}`);
                console.log(` message Preparing to save message from sender=: ${sender}, text messageText=: ${messageText},`);
                if (!sender || !messageText) {
                    console.error('message Sender or message text is undefined. Message data:', data);
                    return; // Отменяем дальнейшие действия, если данные некорректные
                }

                console.log(` message Preparing to save message from: ${sender}, text: ${messageText}`);


                // !!!!  Здесь добавьте логику к сохранению сообщения в базе данных !!!!!
                // const timestamp = new Date().toISOString();
                // Проверка принадлежности домена
                const domainSnapshot = await domainsRef.child(domain).once('value');
                const domainData = domainSnapshot.val();
                const defaultUserAdmin = 'Nqt1vRYDMwVaAdtSUVqVCtXlxq03';

                let userAdmin;
                if (domainData && domainData.UserAdmin) {
                    userAdmin = domainData.UserAdmin;
                    console.log(`connection Owner of domain ${domain} is UserAdmin: ${userAdmin}`);
                } else {
                    userAdmin = defaultUserAdmin; // Значение по умолчанию
                    await domainsRef.child(domain).set({UserAdmin: userAdmin});
                    console.log(` connection No owner found for domain ${domain}, setting UserAdmin to default value ${userAdmin}`);
                }

                // Сохраняем или находим идентификатор чата для пользователя
                const chatSnapshot = await chatsRef.orderByChild('user1').equalTo(userId).once('value');
                let chatId;
                if (chatSnapshot.exists()) {
                    // Если чат уже существует, получаем его ID
                    chatId = Object.keys(chatSnapshot.val())[0];
                    console.log(` connection Chat found for user ${userId}: ${chatId}`);
                } else {
                    // Если чата нет, создаем новый
                    chatId = chatsRef.push().key;

                    // Записываем данные чата
                    await chatsRef.child(chatId).set({
                        user1: userId,
                        user2: userAdmin // Устанавливаем значение владельца домена
                    });
                    console.log(` connection New chat created for user ${userId}: ${chatId}`);
                }


                //my
                await usersRef.child(userId).set({
                    domain: domain,
                    userId: userId,
                    connectionTime: new Date().toISOString(),
                    text: messageText
                });

                // Сохранение чата и отправка сообщения
                // const messageText = data.messageText;

                // const sender = data.sender;
                const timestamp = new Date().toISOString(); // Используйте текущую дату

                // Проверьте все значения
                console.log(`connection Preparing to save message from sender=: ${sender}, text messageText= ЭТО КОННЕКТЕД ТИП, chatId: ${chatId}`);

                // Сохраняем сообщение в подкатегории messages
                await chatsRef.child(chatId).child('messages').push().set({
                    date: timestamp,
                    ownerId: sender,
                    text: messageText,
                    domain: domain
                });

                console.log(` connection Message saved to Firebase`);

                // Сохраните сообщение в Firebase здесь...

                //---------------------------------------------------------------------------
                //MY NEW


            }

        } catch (error) {
            console.error('Error processing message:', error);
        }
    });

    ws.on('close', () => {
        console.log('Client disconnected');
    });

    ws.on('error', error => {
        console.error('WebSocket error:', error);
    });
});

console.log('WebSocket server started on port 8081');

→ Ссылка