React Redux: Issue with Loading and Rendering Firestore Data

I’m encountering an issue with loading and rendering product information from a Firestore database in my React application. I’m using Redux to manage the application state and attempting to fetch data from Firestore using Redux Thunks.

The problem I’m facing is that when I access the data, it only returns the initial state of Redux, with an empty data array and a status of ‘idle’. I’m not sure why this is happening, and I would appreciate any help or insights into what might be causing this issue.

App.js

import Home from "./pages/Home";
import ProductList from "./Components/ProductList";
import SingleProductPage from "./Components/SingleProductPage";
import RegisterPage from "./Components/RegisterPage";
import LoginPage from "./Components/LoginPage";
import ShoppingCart from "./Components/ShoppingCartFolder/ShoppingCart";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { onAuthStateChanged, getAuth } from "firebase/auth";
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { getProductsData } from "./Features/dataFromFireStore/LoadDataFireStore";
import { userSignInAccount } from "./Features/signUpSignInFeature/SignUpSignIn";

function App() {
  const dispatch = useDispatch();

  const getProductsDataFunction = async () => {
    await dispatch(getProductsData());
  }

  let user = useSelector(state => state.signInSignUp.user);

  useEffect(() => {
    getProductsDataFunction();
  }, []);

  // ... rest of your code
}

export default App;

LoadDataFireStore.js:

import { createSlice,createAsyncThunk } from '@reduxjs/toolkit'

import { firebaseFireStoreDB } from '../../FirebaseConfiguration/Firebase';
import { collection,getDocs } from 'firebase/firestore';
import { async } from '@firebase/util';

const initialState = { 
    data: [],
    status:'idle'
 };

const LoadDataFromFireStore = createSlice(
       
        {
            name:"DataFromFireStore",
            // to asscess the splice data use the key of which you pass the reducer function
            initialState,
            reducers:{
                // loadFromFireStore:(state,action)=>{
                //     state.data=action.payload;
                //     // state.data.push(action.payload)
                // }
            },
            extraReducers:(builder)=>{
     
                builder
                .addCase(getProductsData.pending,(state)=>{
                          state.status="pending"
                })
                .addCase(getProductsData.fulfilled, (state,action)=>{
                            state.data=action.payload;
                            state.status="idle"
                })
                .addCase(getProductsData.rejected,(state)=>{
                            state.status="rejected"
                            console.log("this is in rejected state");
                })
            }

            
        }
)

export const getProductsData = createAsyncThunk("getProductsData", async()=>{
    const collectionRef= collection(firebaseFireStoreDB,"products");
                    let productdata=[];
                       let data=await getDocs(collectionRef)
                    
                       productdata=data.docs.map( (doc) => ({
                                ...doc.data(),
                                id:Number(doc.id) 

                       }
                          ));
                       
                       console.log(productdata);
                       return productdata;
                        // .then((productData)=>{
                           
                            
                        //                 productData.docs.forEach((doc)=>{
                        //                             productdata.push( {...doc.data(), id:Number(doc.id)})   
                        //                 })
                        //                 // console.log(productdata);
                                            
                        // })
                        // .catch((error)=>{
                        //         console.log("error while fetching...  "+error);
                        // })
    

})

// export function getProducts(){ // this is trunk action createor function
//     // for both function inner fuction and outer fuction can use normal syntax or arrow syntax i'm using both functions
 
//     return async(dispatch,getstate)=>{// this is actual trunk function

//                 const collectionRef= collection(firebaseFireStoreDB,"products");
//                 const productdata=[];
//                 await getDocs(collectionRef)
//                     .then((productData)=>{
                       
                        
//                                     productData.docs.forEach((doc)=>{
//                                                 productdata.push( {...doc.data(), id:Number(doc.id)})   
//                                     })
//                                     // console.log(productdata);
                                        
//                     })
//                     .catch((error)=>{
//                             console.log("error while fetching...  "+error);
//                     })

//                    await dispatch( loadFromFireStore(productdata) )  
//                     // the above function is similar to dispatch(loadFromFireStore(productdata))
//     }
// }

export const {loadFromFireStore} = LoadDataFromFireStore.actions;
export default LoadDataFromFireStore.reducer;

Products.js

import React, { useEffect, useState } from 'react'
import Product from './Product'
// import { ProductsData } from '../ImportantData';
import  "../../projectStyling/Products.css"
import {Row,Col, Spin} from "antd"
import { firebaseFireStoreDB } from '../../FirebaseConfiguration/Firebase'; 
import { getDocs,collection } from 'firebase/firestore';
import { getProductsData } from '../../Features/dataFromFireStore/LoadDataFireStore';
import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
function Products() {
const dispatch = useDispatch()
//     const [productsData,setProductsData]=useState([])
//  const [loading,setLoading]=useState(true);
    useEffect(    
        // fetching database details...
        ()=>{
// now there is an update we need to access the products data from the Redux store which we called firebaseStore for this
//    let mydata= dispatch( getProductsData() );          
//    console.log(mydata);
//    console.log("this is my data variable above"); 
   // its needed just for checking purpose
//  const fetch= async()=>{
            //     const collectionRef= collection(firebaseFireStoreDB,"products");
           
            //     await getDocs(collectionRef)
            //         .then((productData)=>{
            //                const productdata=[];
            //                         productData.docs.forEach((doc)=>{
            //                                     productdata.push( {...doc.data(), id:Number(doc.id)})   
            //                         })

            //                         setProductsData(productdata);
            //                         // console.log(productsData);
            //                         setLoading(false)
            //         })
            //         .catch((error)=>{
            //                  console.log("error while fetching...  "+error);
            //         })
            // }
            //     fetch();
        },[]);
    
            
            const productsData= useSelector( state => state.fireStore )
            console.log(productsData);
            //  the problem was i was not call the correct splice name to that is the reason.

            // console.log(" if products is shown then redux state data is successfully loaded");
            // console.log(productsData);

            if(productsData.status === 'pending'){
                <Spin size="large"></Spin>
        }  
           
    return (
        <div className="ProductsContainer">
        <h2 style={{textAlign:"center"}}>OUR PRODUCTS</h2>
        {/* we have to give unique key for our indivial array item for react 
         we can do this my 2 stuff
         1. one is by giving the index of array directly 
         2. Giving your own data*/}
         
            <Row
            gutter={[20,35]}
            // wrap={true}
            
            className="GridRowStyling"
            
             >
{/*  products state*/}
         
       
         
         {
            /* loading? (<Spin size="large" />):( */             
            
            productsData.data.map((productData)=>(
            
             
                <Col   className="GridColumn"  key={productData.id}>
                
                <Product  data={productData}  />
                
                </Col>
                
            ))
    /* )  */
    }
          
           </Row>
        </div>
    )
}

export default Products;

Leave a Comment