Firestore更新操作错误覆盖用户数据问题求助
Firestore更新操作偶发用户数据错误覆盖问题
问题详情
- 使用Firebase Authentication的
signInWithEmailAndPassword完成身份验证 - 用户数据以唯一ID为标识存储在Firestore中
- 后台仪表盘支持展示所有用户并提供编辑功能
- 核心异常:编辑某用户数据时,偶尔会错误覆盖另一用户的Firestore文档,导致数据丢失
示例场景
用户A(ID dv6d...)和用户B(ID pzF1...),编辑用户B的数据时,有时会意外覆盖用户A的文档,造成用户A的数据丢失。
相关代码
展示所有用户的组件代码
function User() { const { deleteData, getData } = useAdmin(); const [userData, setUserData] = useState([]); const [page, setPage] = useState(1); const [selectedUser, setSelectedUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const resultsPerPage = 10; const handleSelectedUser = (user) => { setSelectedUser(user); setIsModalOpen(true); }; useEffect(() => { const loadUserData = async () => { await getData("Users", setUserData); }; loadUserData(); }, []); return ( <> <TableContainer> <Table> <TableHeader> <tr> <TableCell>Full Name</TableCell> <TableCell>Email</TableCell> //similar other entries </tr> </TableHeader> <TableBody> {userData.slice((page - 1) * resultsPerPage, page * resultsPerPage).map((user, i) => ( <TableRow key={i}> <TableCell>{user?.fullName}</TableCell> <TableCell>{user?.email}</TableCell> <TableCell> <Button onClick={() => handleSelectedUser(user)}>Edit</Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> {selectedUser && ( <EditUser user={selectedUser} isModalOpen={isModalOpen} closeModal={() => setIsModalOpen(false)} /> )} </> ); }
编辑用户组件代码
export const EditUser = ({ user, isModalOpen, closeModal }) => { const [updatedData, setUpdatedData] = useState({ ...user }); const { updateData } = useAdmin(); const handleSave = async () => { await updateData(user?.id, "Users", updatedData, setLoading); closeModal(); }; const handleChange = (e) => { setUpdatedData({ ...updatedData, [e.target.name]: e.target.value }); }; return ( <Modal isOpen={isModalOpen} onClose={closeModal}> <ModalHeader>Edit User</ModalHeader> <ModalBody> <Input name="fullName" defaultValue={user?.fullName} onChange={handleChange} /> <Input name="email" defaultValue={user?.email} onChange={handleChange} /> </ModalBody> <ModalFooter> <Button onClick={handleSave}>Save</Button> </ModalFooter> </Modal> ); };
AdminContext状态管理代码
// removed necessary imports for better readability const AdminContext = createContext(); export const useAdmin = () => useContext(AdminContext); export const AdminProvider = ({ children }) => { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const updateData = async (docId, dbName, updatedData, setLoading) => { try { setLoading(true); const docRef = doc(db, dbName, docId); await runTransaction(db, async (transaction) => { const docSnapshot = await transaction.get(docRef); if (!docSnapshot.exists()) { throw new Error("Document does not exist!"); } const { id, ...dataWithoutId } = updatedData; // Perform the update within the transaction transaction.update(docRef, dataWithoutId); }); toastSuccess(`${dbName} Updated Successfully`); } catch (error) { toastError(error.message); setError(error.message); } finally { setLoading(false); } }; const getData = useCallback(async (dbName, setloading, setData) => { setloading(true); try { const data = []; const querySnapshot = await getDocs(collection(db, dbName)); querySnapshot.forEach((doc) => { data.push({ id: doc.id, ...doc.data() }); }); setData(data); setloading(false); } catch (error) { toastError(error.message); setError(error.message); setloading(false); } }, []); const value = { updateData, getData }; return ( <AdminContext.Provider value={value}> {children} </AdminContext.Provider> ); };
内容的提问来源于stack exchange,提问作者Shailendra Singh
相关产品推荐
相关产品推荐

