如何用React和Firestore匹配当前ID对应同regNo值的集合文档
解决Firestore通过URL动态查询同regNo文档的问题
需求概述
通过useParams获取URL中的当前文档ID,查询Firestore的dentist集合中,所有与该文档regNo字段值相同的文档。
核心思路
实现该功能需要两步核心操作:
- 根据URL中的ID,先获取对应文档的
regNo值 - 用拿到的
regNo值,查询集合中所有regNo匹配的文档
解决方案代码
单次查询版本(非实时)
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { db } from './firebaseConfig'; // 你的Firebase配置文件 import { doc, getDoc, collection, query, where, getDocs } from 'firebase/firestore'; const DentistList = () => { const [data, setData] = useState([]); const { userId } = useParams(); const currentDocId = userId; useEffect(() => { const fetchMatchingDocs = async () => { if (!currentDocId) return; try { // 第一步:获取当前ID对应的文档,提取regNo const currentDocRef = doc(db, 'dentist', currentDocId); const currentDocSnap = await getDoc(currentDocRef); if (!currentDocSnap.exists()) { console.log('当前文档不存在'); setData([]); return; } const currentRegNo = currentDocSnap.data().regNo; // 第二步:查询所有regNo匹配的文档 const collectionRef = collection(db, 'dentist'); const q = query(collectionRef, where('regNo', '==', currentRegNo)); const querySnap = await getDocs(q); const medData = querySnap.docs.map(doc => ({ id: doc.id, ...doc.data() })); setData(medData); console.log('匹配的文档:', medData); } catch (err) { console.error('查询出错:', err); setData([]); } }; fetchMatchingDocs(); }, [currentDocId]); return ( <div> {/* 渲染匹配到的文档内容 */} {data.map(item => ( <div key={item.id}> <p>文档ID: {item.id}</p> <p>注册编号: {item.regNo}</p> {/* 渲染其他字段 */} </div> ))} </div> ); }; export default DentistList;
实时监听版本(自动同步数据变化)
如果需要实时同步Firestore的数据更新,将getDocs替换为onSnapshot即可:
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { db } from './firebaseConfig'; import { doc, getDoc, collection, query, where, onSnapshot } from 'firebase/firestore'; const DentistList = () => { const [data, setData] = useState([]); const { userId } = useParams(); const currentDocId = userId; useEffect(() => { let unsubscribe; const setupRealtimeListener = async () => { if (!currentDocId) return; try { const currentDocRef = doc(db, 'dentist', currentDocId); const currentDocSnap = await getDoc(currentDocRef); if (!currentDocSnap.exists()) { console.log('当前文档不存在'); setData([]); return; } const currentRegNo = currentDocSnap.data().regNo; const collectionRef = collection(db, 'dentist'); const q = query(collectionRef, where('regNo', '==', currentRegNo)); // 实时监听数据变化 unsubscribe = onSnapshot(q, (querySnap) => { const medData = querySnap.docs.map(doc => ({ id: doc.id, ...doc.data() })); setData(medData); console.log('实时更新的匹配文档:', medData); }, (err) => { console.error('监听出错:', err); }); } catch (err) { console.error('初始化监听出错:', err); setData([]); } }; setupRealtimeListener(); // 组件卸载时取消监听 return () => { if (unsubscribe) unsubscribe(); }; }, [currentDocId]); return ( <div> {data.map(item => ( <div key={item.id}> <p>文档ID: {item.id}</p> <p>注册编号: {item.regNo}</p> </div> ))} </div> ); }; export default DentistList;
你之前代码的问题点
- 错误的文档/集合引用:
collection(db,dentist/${id})写法错误,dentist/${id}是单个文档的路径,应该用doc(db, 'dentist', id)获取单个文档引用,而非collection。 - 缺失regNo获取步骤:没有先根据URL中的ID拿到对应文档的regNo值,直接写死查询条件,无法实现动态匹配。
内容的提问来源于stack exchange,提问作者Deezy
相关产品推荐
相关产品推荐

