I am trying to query my firestore database using getDocs() and using a state to store the products within the "category1" collection. This is to be able to render all the products within the "category1" collection using React.
This is my Category.jsx file:
import React, { useState, useEffect } from "react";
import Product from "./Product";
import { getDocs, collection } from "firebase/firestore";
import db from "../firebase.config";
function Category(props) {
const [products, setProducts] = useState([]);
const fetchProducts = async () => {
const querySnapshot = await getDocs(collection(db, props.id));
querySnapshot.docs.forEach((doc) => {
setProducts([...products, { ...doc.data(), id: doc.id }]);
});
};
useEffect(() => {
fetchProducts();
}, []);
return (
<div>
<h1>{props.name}</h1>
{products &&
products.map((product) => {
const { productName, image, price, description } = product;
return (
<Product
key={product.id}
productName={productName}
image={image}
price={price}
description={description}
/>
);
})}
</div>
);
}
export default Category;
My Firestore database contains these two documents:
{
description: "this is an example product",
id: "6B5RqpuTMwg4hRhmOSwZ",
image: "imagelink",
price: 199,
productName: "Product 1"
},
{
description: "this is another product",
id: "a4VUpJMTvwh9tDsFyaxy",
image: "imagelink",
price: 299,
productName: "Product 2"
}
The result is only Product 2 showing up. When I console.log(products) I can see that product 1 is inside the products state and then is replaced by product 2.
Thanks
Calls to setProducts execute asynchronously, so the multiple calls you do likely are getting into each other's way.
const fetchProducts = async () => {
const querySnapshot = await getDocs(collection(db, props.id));
let theseProducts = querySnapshot.docs.map((doc) => {
return { ...doc.data(), id: doc.id };
})
setProducts([...products, ...theseProducts]);
}