我正在使用 Firebase 9 和 React 18 制作一个聊天应用程序。
在
UsersList.jsx
我有:
import { useLocation } from 'react-router-dom';
import { useEffect, useState, useContext } from 'react';
import { AuthContext } from "../../contexts/AuthContext";
import { serverTimestamp, or, collection, query, limit, where, getDocs } from "firebase/firestore";
import { db } from "../../firebaseConfig";
import { doc, getDoc, setDoc, updateDoc } from "firebase/firestore";
import ConversationsList from './ConversationsList';
import UserItem from './UserItem';
export default function UsersList({ isSearch, searchQuery }) {
const location = useLocation();
const [users, setUsers] = useState([]);
const [error, setError] = useState(false);
const { currentUser } = useContext(AuthContext);
const searchUsers = async () => {
const q = query(collection(db, "users"),
or(
where('firstName', '==', searchQuery),
where('lastName', '==', searchQuery),
where('email', '==', searchQuery)
), limit(10));
try {
const querySnapshot = await getDocs(q);
const usersArray = [];
querySnapshot.forEach(doc => {
if (doc.data() !== null) {
usersArray.push(doc.data());
}
});
setUsers(usersArray);
} catch (error) {
setError(true);
}
}
const selectUser = async (user) => {
const conversationId = currentUser.uid > user.uid ? `${currentUser.uid}${user.uid}` : `${user.uid}${currentUser.uid}`;
try {
const response = await getDoc(doc(db, "contentConversations", conversationId));
if (!response.exists()) {
// Content conversations
await setDoc(doc(db, "contentConversations", conversationId), { messages: [] });
// Sidebar conversations
await setDoc(doc(db, "conversations", currentUser.uid), {
[conversationId + ".userInfo"]: {
uid: user.uid,
firstName: user.firstName,
lastName: user.lastName,
avatar: user.avatar,
},
[conversationId + ".date"]: serverTimestamp(),
});
await setDoc(doc(db, "conversations", user.uid), {
[conversationId + ".userInfo"]: {
uid: currentUser.uid,
firstName: currentUser.firstName,
lastName: currentUser.lastName,
avatar: currentUser.avatar,
},
[conversationId + ".date"]: serverTimestamp(),
})
}
} catch (error) {
console.log(error)
}
}
const usersList = () => {
return users.map(user => (
<UserItem
key={user.uid}
user={user}
selectUser={selectUser}
/>
))
}
useEffect(() => {
searchUsers();
}, [location, setUsers, searchUsers])
return (
<>
{isSearch ?
<div className="chat-users">
{!users.length ? <p className="m-0 text-center text-danger">No users found</p> :
<PerfectScrollbar>
<ul className="list list-unstyled m-0 d-table w-100">
{ usersList() }
</ul>
</PerfectScrollbar>
}
</div> : <ConversationsList />
}
</>
);
}
我希望当“当前用户”单击通过执行搜索找到的用户项目时创建一个新对话。
如果存在与一个用户 (John Smith) 的对话,则与新用户 (John Doe) 的新对话将覆盖前一个对话。
当你调用 setDoc(reference, data) 时:
写入指定
引用的文档。如果该文档尚不存在,则会创建它。DocumentReference
如果文档已存在,它将被覆盖。如果您想添加一个新文档而不覆盖现有文档,那么您必须使用 addDoc(reference, data) 其中:
使用给定数据将新文档添加到指定的
,并自动为其分配文档 ID。CollectionReference