Home > front end >  Custom Hook Returning Empty Array From Firestore
Custom Hook Returning Empty Array From Firestore

Time:04-29

I'm a newly self-taught coder. Hopefully I'm expressing my situation adequately.

I'm trying to retrieve some data from Cloud Firestore. I've made a custom hook that should useState and setDocuments to the be the retrieved "guide". The query uses useParams to get the id to match to the specific guide I'm trying to get. I think the issue is in the querySnapshot. setDocuments doesn't seem to be working. When I console log "documents" it's an empty array.

Any leads?

import { useParams } from 'react-router-dom'
import { collection, query, where, getDocs } from "firebase/firestore";
import { db } from "../firebase/config"
import { useEffect } from 'react';

export const useGuide = (c) => {
  const [documents, setDocuments] = useState([])
  const { id } = useParams()

  useEffect(() => {

    const ref = collection(db, c)
    const q = query(ref, where("id", "==", `${id}`))

    getDocs(q).then(querySnapshot => {
      querySnapshot.forEach((doc) => {
        setDocuments(doc.data()) 
      });
    });
  }, [])

  console.log(documents)

  return { documents }
}

Here is where I try to use the hook useGuide to set the state which would be passed to a component.

import SingleGuide from '../../components/SingleGuide/SingleGuide'
import { useGuide } from '../../hooks/useGuide'

function Guide() {
    const { documents: guides } = useGuide('guides')
    console.log(guides)
                
  return (
      <div>
          {guides && <SingleGuide guide={guides}/>}
      </div>
  )
}

export default Guide

CodePudding user response:

There are a few issues with your code including setting an array of docs equal to a single doc in the query results. Try something like the following.

import { useParams } from "react-router-dom";
import { collection, query, where, getDocs } from "firebase/firestore";
import { db } from "../firebase/config";
import { useState, useEffect } from "react";

export const useGuide = (c) => {
  const [documents, setDocuments] = useState([]);
  const { id } = useParams();

  useEffect(() => {
    // create array to hold all the individual docs
    const docs = [];
    const ref = collection(db, c);
    const q = query(ref, where("id", "==", `${id}`));

    getDocs(q).then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        docs.push(doc.data());
      });

      setDocuments(docs);
    });
  }, [c]); // could consider passing `id` to the hook instead of useParams and adding that as a dependency to update data automatically

  console.log(documents);

  return { documents };
};

  • Related