首页 > 解决方案 > 如何防止firebase多次显示一条消息

问题描述

我正在使用 firebase 聊天消息。当我提交已发送消息的表单时,所有消息都会重复并从头到尾获取。为了更好地理解,请看下面的图片。 在此处输入图像描述

这是我实际在做什么的代码。

user_chats.onSnapshot((querySnapshot) => {
            querySnapshot.forEach(doc => {
                user_messages.push(doc.data());
            });
            showMessages();
        });
function showMessages()
    {
        for (let i =0;i<user_messages.length;i++)
        {
            let user_id = user_messages[i].user_id;
            if (user_id == auth_id)
            {
                let selector = $('#my_msg .row');
                selector.find('.chat').text(user_messages[i].message);
                selector.clone().appendTo('.msg_area_div');
            }
            else{
                let selector = $('#user_msg .row');
                selector.find('.chat').text(user_messages[i].message);
                selector.clone().appendTo('.msg_area_div');
            }
        }
    }

在这里,我想显示唯一推送的新项目,而不是所有旧消息 帮助我解决这个问题。TIA

已编辑

使用@Frank van Puffelen的解决方案后

function fetchMessage() {
            let document_id = documentID();

        let table = db.collection("chat").doc(document_id).collection('chats');
        let user_chats = table.orderBy('created_at');

        user_chats.onSnapshot((querySnapshot) => {
            querySnapshot.docChanges().forEach(change => {
                if (change.type === "added") {
                    user_messages.push(change.doc.data());
                }
            });
            showMessages();
        });
    }
    function showMessages() {
        $('.msg_area_div').empty();
        for (let i = 0; i < user_messages.length; i++) {
            let active_user_id = user_messages[i].user_id;

            if (active_user_id == auth_id) {
                let selector = $('#my_msg .row');
                selector.find('.chat').text(user_messages[i].message);
                selector.clone().appendTo('.msg_area_div');
            } else {
                let selector = $('#user_msg .row');
                selector.find('.chat').text(user_messages[i].message);
                selector.clone().appendTo('.msg_area_div');
            }
        }
        scrollDown();
    }

得到这样的结果 在此处输入图像描述

标签: javascriptjqueryfirebasegoogle-cloud-firestore

解决方案


由于您正在循环QuerySnapshot自身,因此您始终会看到循环内的所有文档 - 即使快照只有一次更改。

这是一个有效的选项,但这意味着您每次onSnapshot被调用时都需要清除并重建整个聊天节点。您可以通过在添加消息之前showMessages清除您的 HTML 来执行此操作:.msg_area_div

$('.msg_area_div').empty();

或者,您可以使用较低级别的属性仅处理通过以下方式添加、更改或删除的文档

snapshot.docChanges().forEach((change) => {
    if (change.type === "added") {
        console.log("New city: ", change.doc.data());
    }
    if (change.type === "modified") {
        console.log("Modified city: ", change.doc.data());
    }
    if (change.type === "removed") {
        console.log("Removed city: ", change.doc.data());
    }
});

推荐阅读