我正在使用 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 我很困惑
您的第二个
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();
}
}, []);