Firebase 数据库更新时重新渲染 React 组件

问题描述 投票:0回答:1

我正在使用 React(vite) 和 Firebase 构建一个聊天应用程序。目前我陷入困境,因为虽然聊天正常,但我无法实时接收消息,只有当我调用 closeChat() 并重新打开时,我才能看到收到的消息。

在附件中您将找到我的 ChatArea 组件。

import ChatBubble from "./ChatBubble";
import MessageCreation from "./MessageCreation";
import { useState, useEffect } from "react";
import { useAuth } from '../AuthContext';
import { getDatabase, ref, child, get, set } from "firebase/database";



export default function ChatArea({ chatId, setCurrentChatId }) {
    const { user } = useAuth();
    const [allMessages, setAllMessages] = useState([]);
    const [friend, setFriend] = useState('');
    const dbRef = ref(getDatabase());

    useEffect(() => {
        get(child(dbRef, 'chats/' + chatId)).then((snapshot) => {
            const chatData = snapshot.val();
            const friend = chatData.firstUser !== user.email ? chatData.firstUser : chatData.secondUser;
            setFriend(friend);
        }).catch((error) => {
            console.error(error);
        });
    }, [chatId]);

    useEffect(() => {
        get(child(dbRef, 'chats/' + chatId + '/messages/')).then((snapshot) => {
            setAllMessages(Object.values(snapshot.val()));
        }).catch((error) => {
            console.error(error);
        });
    }, []);

    function closeChat() {
        setCurrentChatId(null); // Set currentChatId to null to close the chat
    }

    function sendMessage(message) {
        const senderText = user.email;
        const messageId = Date.now();
        const chatRef = ref(getDatabase(), 'chats/' + chatId + '/messages/' + messageId);
        set(chatRef, {
            sender: senderText,
            content: message,
            send_time: Date.now()
        }).then(() => {
            setAllMessages([...allMessages, { sender: senderText, content: message }]);
            console.error(allMessages);
        }).catch((error) => {
            console.error("Error sending message:", error);
        });
    }


    return (
        <div className="container-md chat-area">
            <div className="chat-area-username" >{friend}<button onClick={closeChat} >X</button></div>
            <div className="conversation-area">
                {allMessages.map((message, index) => (
                    <div key={index} className="convo-container">
                        <ChatBubble sender={message.sender === user.email ? "currentUser" : "nope"} message={message.content} />
                    </div>
                ))}
            </div>
            <div className="message-creation-area">
                <MessageCreation onSendMessage={sendMessage} />
            </div>
        </div>
    );
}


我尝试像这样使用 Firebase 的 onValue 方法

useEffect(() => {
        const conversationRef = ref(dbRef, 'chats/' + chatId + '/messages/');
        onValue(conversationRef, (snapshot) => {
            if (snapshot.exists()) {
                setAllMessages(Object.values(snapshot.val()));
            } else {
                setAllMessages([]);
            }
        });
    }, [chatId]);

我收到以下错误: TypeError: db._checkNotDeleted is not a function 我很困惑

reactjs firebase-realtime-database vite-reactjs
1个回答
0
投票

您的第二个

useEffect
,将您的
get
更改为
onSnapshot
以添加实时收集侦听器。 https://firebase.google.com/docs/firestore/query-data/listen

类似这样的:

useEffect(() => {
        const unsubscribe = onSnapshot(dbRef, 'chats/' + chatId + '/messages/')).then((snapshot) => {
            setAllMessages(Object.values(snapshot.val()));
        }).catch((error) => {
            console.error(error);
        });
        return () => {
            unsubscribe();
        }
    }, []);
© www.soinside.com 2019 - 2024. All rights reserved.