I want to get some data from firestore and then display it in JSX style. This is why I have used useEffect() in the following code as I want all the promises to be resolved and the data to be in the variable before I return my react component. This component works when I manually define the data as an object in javascript so the error lies in firestore returning an empty array, not the react code.
This is my programme :
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { addDoc, collection, onSnapshot } from "firebase/firestore";
import { db } from "../data/firestore-data";
import { UserAuth } from "../context/AuthContext";
export default function ProductPage() {
const [products, setProducts] = useState([]);
useEffect(() => {
const productsRef = collection(db, "products");
getDocs(productsRef).then((res) => {
const ords = res.docs.map((doc) => ({
data: doc.data(),
id: doc.id,
}));
const products = ords.map((ord) => ({
id: ord.id,
name: ord.data.name,
price: ord.data.price,
imageSrc: ord.data.imageSrc,
imageAlt: ord.data.imageAlt,
productDescription: ord.data.productDescription,
}));
setProducts(products);
});
}, []);
const productID = useParams().id;
console.log(productID);
const [count, setCount] = useState(1);
const incrementCount = () => {
setCount(count + 1);
};
const decrementCount = () => {
if (count >= 2) {
setCount(count - 1);
}
};
console.log("Template : ");
console.log(products);
const product = products.find((obj) => obj.id === productID);
const productName = product.name;
const productPrice = product.price;
const img = product.imageSrc;
const productDescription = product.productDescription;
const imgSize = 600;
const { user } = UserAuth();
function AddOrder() {
console.log("Working...");
const ordersRef = collection(db, "orders");
addDoc(ordersRef, {
ProductID: productID,
UserID: user.uid,
}).then((res) => {
console.log(res);
});
}
return (
<React.Fragment>
<div className="m-[70px] ml-[130px] flex flex-row items-start font-mono">
<img
className="mt-0 rounded-lg"
style={{ width: imgSize, height: imgSize }}
src={img}
alt={productName}
/>
<div className="mx-[90px] flex-grow space-y-9">
<h1 className="text-5xl">{productName}</h1>
<p className="text-lg font-bold">Available At: ${productPrice}</p>
<p className="text-lg">{productDescription}</p>
<div className="flex space-x-3">
<div className="inline-flex h-[50px] flex-grow basis-1/4 items-center justify-center space-x-4 py-2 px-4">
<button
className="h-[25px] w-[25px] border-2 border-solid border-orange-600 text-center hover:bg-orange-600"
onClick={decrementCount}
>
-
</button>
<span className="text-center text-xl text-black">{count}</span>
<button
className="h-[25px] w-[25px] border-2 border-solid border-orange-600 text-center hover:bg-orange-600"
onClick={incrementCount}
>
+
</button>
</div>
<button className="h-[50px] flex-grow basis-3/4 items-center rounded bg-orange-600 py-2 px-4 hover:bg-orange-500">
<button
className="text-center text-xl font-bold text-white"
onClick={AddOrder}
>
Buy Now
</button>
</button>
</div>
</div>
</div>
</React.Fragment>
);
}
When that didn't work I tried with the onSnapshot() function as well but it returned the same empty array. My code for that was :
useEffect(() => {
const productsRef = collection(db, "products");
onSnapshot(productsRef, (snapshot) => {
setProducts(
snapshot.docs.map((doc) => ({
id: doc.id,
name: doc.data.name,
price: doc.data.price,
imageSrc: doc.data.imageSrc,
imageAlt: doc.data.imageAlt,
productDescription: doc.data.productDescription,
}))
);
});
}, []);
This is an image of the console (the errors are because I'm trying to access values of an object that's an empty array but they'll get solved when the empty array part does). The error message and empty array is the same for the both getDocs() and onSnapshot():

If you need any context or the code of some of the files I have imported please let me know by commenting on this question.
Edit: Added image of the console