React Native中基于Firebase登录用户从Firestore获取数据失败
React Native + Firebase 根据登录用户获取Firestore数据失败问题
我正在使用React Native和Firebase,尝试根据用户登录状态从Firestore获取对应用户的数据,相关代码如下:
const UserInbox = () => { const auth = getAuth(app) const messages = query(collection(db, "feedback"), where("reciepent","==", userData? auth.currentUser.email:'unknown')) const [userData, setUserData] = useState([]) const [messageText,setMessageText]=useState("") const fetchData = async()=>{ const unsubscribe = auth.onAuthStateChanged(async user => { const list = []; if(user){ await getDocs(messages) .then((querySnapshot) => { querySnapshot.forEach((doc) => { const {userId,recipient,messageText} = doc.data() list.push({ id:doc.id, userId, recipient, messageText }) console.log(doc.data()); setUserData(list) }); }) } else{ setUserData(null) } }) return () => unsubscribe(); } }
问题:当我把查询条件从
const messages = query(collection(db, "feedback"), where("email","==", userData? auth.currentUser.email:'unknown'))
替换为固定条件
const messages = query(collection(db, "feedback"), where("city", "==", "CA"))
时,代码能正常按条件获取数据,但使用当前登录用户的信息作为where条件时,页面仅显示空白,没有任何数据返回。

问题原因及修复方案
1. 查询初始化时机错误
组件初始化时auth.currentUser可能还未完成加载,此时创建的messages查询会使用'unknown'作为条件,自然查不到数据。应该在onAuthStateChanged回调内,确认用户已登录后再构建查询。
2. 字段名拼写错误
代码中where条件用了"reciepent",但从doc.data里解构的是recipient,字段名拼写不一致,导致查询无法匹配到对应数据。
3. 状态更新逻辑不合理
在forEach循环内每次调用setUserData会触发多次组件渲染,应该等所有文档处理完成后再统一更新状态。
4. async/await与then混合使用
代码同时用了await和.then(),写法混乱,统一使用async/await更易维护。
修正后的代码
const UserInbox = () => { const auth = getAuth(app); const [userData, setUserData] = useState([]); const [messageText, setMessageText] = useState(""); const fetchData = () => { // 监听用户登录状态变化 const unsubscribe = auth.onAuthStateChanged(async (user) => { if (user) { try { // 用户已登录,基于用户邮箱构建查询(注意字段名拼写正确) const messagesQuery = query( collection(db, "feedback"), where("recipient", "==", user.email) ); const querySnapshot = await getDocs(messagesQuery); const list = []; querySnapshot.forEach((doc) => { const { userId, recipient, messageText } = doc.data(); list.push({ id: doc.id, userId, recipient, messageText }); }); // 所有文档处理完成后统一更新状态 setUserData(list); } catch (error) { console.error("获取数据失败:", error); } } else { // 用户未登录,清空数据 setUserData([]); } }); // 返回卸载时的取消监听函数 return () => unsubscribe(); }; // 组件挂载时调用fetchData useEffect(() => { const unsubscribe = fetchData(); return unsubscribe; }, []); // 渲染逻辑... };
内容的提问来源于stack exchange,提问作者Omar Bakoban
相关产品推荐
相关产品推荐

