next.js 如何在Firestore NextJS上执行内部连接查询

vh0rcniy  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(171)

我有这两个收藏品存储在Firestore上。

正如您所看到的,用户的“uid”字段和“annuncios”的“createdBy”字段具有相同的字符串数据,因为应用程序的理念是创建的每个“annuncio”都具有其创建者的信息。我想在我的应用程序上显示每一个as this的创建者的名字。我不知道如何将我在users集合中的信息与我在anuncios集合中的信息进行精确匹配。我必须显示来自users的“displayName”,但要做到这一点,我必须将该信息与我在anuncios中的“createdBy”进行比较。如果使用SQL,我会简单地做一个连接查询,但由于NO-SQL数据库不能执行,我有点不知道如何实现这一点。顺便说一下,这是我目前如何获得公告数据并将其显示在我的前端。

const [anuncios, setAnuncios] = useState([])
const [creadorAnuncio, setCreadorAnuncio] = useState([])
const [loading, setLoading] = useState(true)

const db = getFirestore(app);

useEffect(() => {

    const itemsRef = query(collection(db, 'anuncios'))
    getDocs(itemsRef)
        .then(res => {
            setAnuncios(res.docs.map((item) => ({ anuncioID: item.id, ...item.data() })
            ))
            setCreadorAnuncio(res.docs.map((item) => (item.data().createdBy)))
        })
        .finally(() => setLoading(false))

}, [])

anuncios.map((anuncio, i) => {
    console.log(creadorAnuncio)
    let q = query(collection(db, "users"), where("uid", "==", creadorAnuncio[i]));
    getDocs(q).then(res => {
        let x = res.docs.map((item) => (item.data().name))
        console.log(x)
    })
})

return(<div>{anuncios.map((anuncio, i) => (
                        <Link href='/' key={anuncio.id}>}</Link></div>)

谢谢
更新:这是我使用@Dharmaraj提供的解决方案得到的结果

useEffect(() => {

    const getAnuncios = async () => {
        // Fetch Anuncios
        const itemsRef = query(collection(db, 'anuncios'))
        const querySnapshot = await getDocs(itemsRef)
        // Array of creator UIDs
        const creatorUids = [...new Set(querySnapshot.docs.map(doc => doc.data().createdBy))]
        //console.log(creatorUids)
        const creatorDocs = await Promise.all(creatorUids.map(uid => getDoc(doc(db, 'users', uid))))
        //console.log(creatorDocs)
        // Store creators data in a Map
        const creators = creatorDocs.reduce((acc, doc) => ({ ...acc, [doc.id]: doc.data() }), {})
        //console.log(creators)
        // Update state after creators data is fetched
        setAnuncios(querySnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id })))
        setCreators(creators)
        console.log(creators)

        anuncios.map(anuncio => (
            console.log(anuncio),
            console.log(creators[anuncio.createdBy]?.name)
        ))
    }

    getAnuncios()
}, [])

pbgvytdp

pbgvytdp1#

如果一个创建者创建了多个 Anuncios,您当前的代码可以多次获取同一个文档。您可以首先Map一个唯一创建者UID数组,查询它们并将其存储在一个对象中,如下所示:

const [anuncios, setAnuncios] = useState([])
const [creators, setCreators] = useState({})

useEffect(() => {
  const getAnuncios = async () => {
    // Fetch Anuncios
    const itemsRef = query(collection(db, 'anuncios'))
    const querySnapshot = await getDocs(itemsRef)
    // Array of creator UIDs
    const creatorUids = [...new Set(querySnapshot.docs.map(doc => doc.data().createdBy))]
    const creatorDocs = await Promise.all(creatorUids.map(uid => getDoc(doc(db, 'users', uid))))

    // Store creators data in a Map
    const creatorsData = creatorDocs.reduce((acc, doc) => ({ ...acc, [doc.id]: doc.data() }), {})

    console.log(creatorsData)

    // Update state after creators data is fetched
    setAnuncios(querySnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id })))
    setCreators(creators)
  }

  getAnuncios()
}, [])

return (
  <div className="App">
    <h1>Anuncios</h1>
    <div>
      {anuncios.map(anuncio => (
        <div className="anuncio" key={anuncio.id}>
          <h2>{anuncio.currency} {anuncio.amount}</h2>
          <p>Created by: {creators[anuncio.createdBy]?.name}</p>
        </div>
      ))}
    </div>
  </div>
)

相关问题