I'm taking the React course at coderhouse and we're taking Firebase's Firestore database; We are setting up a virtual store and we have to bring the articles from the database, I have the following problem when I want to bring the articles of a category it brings it to me but when I want them to load everything, what would it be in the index the page does not load.
Can you tell me why? Thank you. I leave you my code and the error it is giving me, how do I solve it, thank you.
React-dom.development.js:22738 Uncaught FirebaseError: Function where() called with invalid data. Unsupported field value: undefined
import React, {useEffect, useState} from "react";
import '../App.css';
import 'materialize-css/dist/css/materialize.css';
import ItemList from './ItemList';
import CircularProgress from '#mui/material/CircularProgress';
import { useParams } from "react-router-dom";
import { db } from '../firebase/firebase';
import { getDocs, collection, query, where, getDoc } from "firebase/firestore";
export const ItemListContainer =() => {
const [swSell,setSwSell] = useState([])
const [cargar,setCargar] = useState(true)
const {categoryID} = useParams();
useEffect(() => {
const productCollection = collection(db, 'Products');
const productQuery = query(productCollection, where('category', '==', categoryID));
const URL= categoryID == null ? productQuery : productCollection;
console.log(URL)
getDocs(URL)
.then(result => {
const lista = result.docs.map(element => {
return {
...element.data(),
}
})
setSwSell(lista);
})
.catch(error => console.err)
.finally(() => setCargar(false));
/* const URL = categoryID
return(
<>
{
<main className="items">
<div className="parent" key={swSell.id}>
{cargar ? <CircularProgress color="primary"/>:<ItemList product={swSell} />}
</div>
</main>
}
</>
);
}
export default ItemListContainer;
You should run the query when categoryID is not null. Hence your ternary operator should be opposite.
const URL = categoryID === null ? productCollection : productQuery;
Related
I am trying to read data from firebase using nextjs but I get back an empty page. Even when I console log, nothing gets returned. This is how my code looks like
import React, {useState} from 'react'
import { db } from '../firebase'
import { collection, getDocs } from "firebase/firestore";
const reference = collection(db, "students");
function Card(props) {
const { studentsData } = props
return (
<div>
<p>This is just a test</p>
{studentsData && studentsData.map(students => (
<p>{students.name}</p>
))}
</div>
)
}
export const getStaticProps = async () => {
const students = await getDocs(reference);
const studentsData = students.docs.map(doc => ({id: doc.id, ...doc.data() }))
console.log(studentsData);
return {
props: { studentsData }
}
}
export default Card
All I get back from this is just an empty page. Where could I be going wrong?.
I keep getting this error
TypeError: Cannot read property 'useState' of null
whenever I try pulling data from the firestore database. The error points to when I am using the useState and this is how my code looks like
import React from 'react'
import { useState } from 'react';
import { db } from '../firebaseconfig'
import { collection, getDocs } from "firebase/firestore";
const reference = collection(db, "students");
const [students, setstudents] = useState([]);
export const getStaticProps = async () => {
const data = await getDocs(reference);
setstudents(data.docs.map(doc => ({...doc.data(), id: doc.id})));
return {
props: students
}
}
function Card({students}) {
return (
<div>
{students.map(student => (
<h1>{student.name}</h1>
))}
</div>
)
}
export default Card
Where could I be going wrong?
In the code snippet you have provided, the state students does not have any other purpose than being sent as props to Card component.
Based on the nextjs docs (https://nextjs.org/docs/basic-features/data-fetching/get-static-props#using-getstaticprops-to-fetch-data-from-a-cms) , modify the code like this and try
import React from 'react'
import { db } from '../firebaseconfig'
import { collection, getDocs } from "firebase/firestore";
const reference = collection(db, "students");
export const getStaticProps = async () => {
const data = await getDocs(reference);
const students=data.docs.map(doc => ({...doc.data(), id: doc.id}));
return {
props: {
students
}
}
}
function Card({students=[]}) {
return (
<div>
{students.map(student => (
<h1>{student.name}</h1>
))}
</div>
)
}
export default Card
From React Docs there are rules to using Hooks.
React Hooks Rules
Your code should look like this:
function Card({students}) {
const [students, setstudents] = useState([]);
return (
<div>
{students.map(student => (
<h1>{student.name}</h1>
))}
</div>
)
}
This should solve your bug.
Change setstudents to setStudents and I suggest simplify your code:
import React, { useState } from 'react'
import { db } from '../firebaseconfig'
import { collection, getDocs } from "firebase/firestore";
function Card() {
const [students, setStudents] = useState([]);
const fetchStudents=async()=>{
const response=db.collection('students');
const data=await response.get();
setStudents(data.docs.map(doc => ({...doc.data(), id: doc.id}))
);
}
useEffect(() => {
fetchStudents();
}, [])
return (
<div>
{students && students.map(student => (
<h1>{student.name}</h1>
))}
</div>
)
}
export default Card
you are using 2 react imports. Make it one
try this:
import React, { useState} from 'react'
I need to fetch all data from the collection but instead only getting one document. I will be grateful for you support. Below, I present the screenshots and code snippet regarding my concern.
enter image description here
enter image description here
import './App.css';
import db from './firebase';
import React,{useState,useEffect} from 'react';
function App() {
const [accounts,setAccounts]=useState([])
const fetchAccounts=async()=>{
const response=db.collection('accounts');
const data=await response.get();
data.docs.forEach(item=>{
setAccounts([...accounts,item.data()])
})
}
useEffect(() => {
fetchAccounts();
}, [])
return (
<div className="App">
{
accounts && accounts.map(account=>{
return(
<div>
<h1>Example</h1>
<h4>{account.date}</h4>
<p>{account.email}</p>
</div>
)
})
}
</div>
);
}
export default App;
Set state functions in React are async. It means that your values are not updated immediately.
So when you update your state in a loop, each time it updates the initial value of the state and because of that at the end of the loop, only 1 item is added to the array.
In order to fix the bug, you should use another variable and set your state after the loop:
import React, { useState, useEffect } from 'react';
import './App.css';
import db from './firebase';
function App() {
const [accounts, setAccounts] = useState([]);
const fetchAccounts = async () => {
const response = db.collection('accounts');
const data = await response.get();
const newAccounts = data.docs.map(item => item.data());
setAccounts(newAccounts);
}
useEffect(() => {
fetchAccounts();
}, [])
return (
<div className="App">
{
accounts && accounts.map(account => {
return(
<div>
<h1>Example</h1>
<h4>{account.date}</h4>
<p>{account.email}</p>
</div>
)
})
}
</div>
);
}
export default App;
I am getting id of single product from backend using match.params but I got error please help me to solve this error
import React, { useEffect } from "react";
import Carousel from "react-material-ui-carousel";
import "./ProductDetail.css";
import { useSelector, useDispatch } from "react-redux";
import { getProductDetails } from "../../actions/productActions";
const ProductDetail = ({ match }) => {
const dispatch = useDispatch();
const { product, loading, error } = useSelector(
(state) => state.productDetail
);
useEffect(
() => {
dispatch(getProductDetails(match.params.id));
},
[dispatch, match.params.id]
);
I am getting this error:
TypeError: Cannot read properties of undefined (reading 'params')
| useEffect(
15 | () => {
16 | dispatch(getProductDetails(match.params.id));
> 17 | },
| ^ 18 | [dispatch, match.params.id]
19 | );
please provide the solution of this or any other way to do this ??
Try adding null coallescing operators to match
useEffect(
() => {
dispatch(getProductDetails(match?.params?.id));
},
[dispatch, match.params.id]
);
Also it would be usefull to check if you are ever getting params and id from match with a console.log(match) somewhere in the code.
Assuming ProductDetail is a dynamic page and you need to access to the params id.
import { useParams } from "react-router-dom";
const { id } = useParams();
useEffect(
() => {
dispatch(getProductDetails(id));
},
[dispatch,id]
);
you can use useParams instead of match
import React, { useEffect } from 'react'
import './productDetails.css'
import Carousel from 'react-material-ui-carousel'
import { useSelector,useDispatch } from 'react-redux'
import { getProductDetails } from '../../actions/productAction'
import { useParams } from 'react-router-dom'
const ProductDetail = ({ match }) => {
const { id } = useParams();
const dispatch = useDispatch()
const { product, loading, error } = useSelector(
(state) => state.productDetails
);
useEffect(()=>{
dispatch(getProductDetails(id))
},[dispatch,id])
I have a problem with taking data from reference data.
The code below is component I made to get Data from Firebase Database. When I executed this, I could get Buses data. Plus, I checked that Users data(Reference) belongs to a bus. However, When I coded to get a user's name, phone, or uuid it failed. What is the reason and How can I resolve it?
import { StyleSharp } from "#mui/icons-material";
import React, { useEffect } from "react";
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../../app/store'
import BusTable from "../../components/BusTable";
import BusTabs from "../../components/Tab";
import { collection, query, onSnapshot } from 'firebase/firestore'
import { db } from './../../app/firebase/FirebaseConfig'
import styles from "./index.module.css";
import { setBuses } from "./../../features/buses/busesSlice";
import { Bus as BusData } from './../../app/firebase/collections/Bus'
const Bus = () => {
const buses = useSelector((state: RootState) => state.buses.buses)
const dispatch = useDispatch()
useEffect(() => {
const q = query(collection(db, 'trips', '5DpHAkIuOpoPZSTzNc5A', 'bus'))
const unsub = onSnapshot(q, (querySnapshot) => {
const buses = new Array(0)
querySnapshot.forEach((doc) => {
buses.push(new BusData(doc.id, '', 1, doc.data().users))
})
dispatch(setBuses({buses: buses}))
console.log(buses) /////SUCCESS TO GET BUSES DATA/////
})
return unsub
}, [dispatch]);
return (
<div>
{buses.map((bus) => (
<div className={styles.busTabs}>
{bus.users.map((user)=>(
<p>{user.uuid}</p> ////CAN'T GET ANY USERS DATA /////
))}
</div>
))}
</div>
);
}
export default Bus;