简体   繁体   中英

Unable to map data of nested firebase/firestore query, React & Typescript

I am trying to render data of sections and lectures within sections by first fetching data from firestore where lectures are also saved within sections. My approach is to first query the section collection and then query its lectures collection using the section id.

In the console I can see the correct outputs for both section data and the nested lecture data. On the webpage I don't get the nested lecture data shown, but when saving code changes they sometimes flash for 0.1 seconds.

I would assume that this points to a problem with rerendering due to the asynchronous nature of the nested query, but I find async functions very confusing and cannot seem to find a way to make them run as I would expect.

import React, {useState, useEffect} from 'react'
import { db } from '../../../firebase-config'
import {collection, onSnapshot, query} from 'firebase/firestore'

type CourseSections =  CourseSection[]

type CourseSection = {
  id: string,
  title: string,
  lectures: CourseLectures,
}

type CourseLectures = CourseLecture[]

type CourseLecture = {
  title: string,
  id: string,
}

const Test2:React.FC = () => {

const [data, setData] = useState<CourseSections>([])

useEffect(()=>{
   async function fetchData() {
      const q = query(collection(db, "products", "5yzLggfe5YC0PAM49enW", "sections"))
      onSnapshot(q, (snapshot)=> {
         let tempSections:CourseSections = []
         snapshot.docs.forEach((doc:any)=>{
            const w = query(collection(db, "products", "5yzLggfe5YC0PAM49enW", "sections", doc.id, "lectures"))
            let tempLectures:CourseLectures = [];
            onSnapshot(w, (snapshotB:any)=>{
               snapshotB.docs.forEach((doc:any)=>{
               tempLectures.push({...doc.data(), id: doc.id})
               })
            })
            tempSections.push({...doc.data(), id:  doc.id, lectures: tempLectures}) //
         })
         setData(tempSections)
      })
   }
   fetchData();
}, [])

return <>
   {data.map((section:CourseSection)=>{
      return <><h2>{section.title}</h2>
         {section.lectures.map((lecture:CourseLecture)=>{
            return <h4>{lecture.title}</h4>
         })}
      </>
   })}
</>
}
export default Test2

I ended up finding a solution to my problem after reading the answer to the following post:

Is there a way to map a sub-collection into a struct while querying the main collection? (Firestore)

So instead of querying a collection and immediately querying its subcollections I am now saving the data from the subcollections in a field that contains an array of maps. This way I can access all the data in one query and don't need nested queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM