Home > Software engineering >  Context userdata is an empty object in useEffect hook
Context userdata is an empty object in useEffect hook

Time:07-22

I have a problem in my code. useEffect cant read imported object. As you see user object is imported from another context. When i try to use this user object in useEffect of DataContext it returns an empty object. I think useEffect is rendered before that state has a value but I don't have idea how to fix it. I want to access user.email in useEffect instead of email([email protected]) so firebase will filter emails and give me the object of current user. Thanks. I am begginer and don't know a lot of things yet.

DataContext.js :

import { createContext, useContext, useEffect, useState } from "react";
import { db, storage, storedb } from "../firebase";
import { uid } from "uid";
import { set, ref, onValue } from "firebase/database";
import {
  doc,
  setDoc,
  updateDoc,
  collection,
  addDoc,
  query,
  where,
  getDocs,
  getDoc,
  onSnapshot,
  collectionGroup,
  limit,
} from "firebase/firestore";
import {
  ref as storageref,
  uploadBytesResumable,
  getDownloadURL,
} from "firebase/storage";
import { useUserAuth } from "./UserAuthContext";

const dataContext = createContext();

export function DataContextProvider({ children }) {
  const { user } = useUserAuth();
  const [category, setCategory] = useState("");
  const [contactnumber, setContactNumber] = useState("");
  const [description, setDescription] = useState("");
  const [price, setPrice] = useState("");
  const [sellername, setSellerName] = useState("");
  const [title, setTitle] = useState("");
  const [imageurl, setImageUrl] = useState("");
  const [imageUpload, setImageUpload] = useState(null);
  const [imageuploaddone, setImageUploadDone] = useState("");
  // Data for Users and Items
  const [items, setItems] = useState([]);
  const [userdata, setUserData] = useState([]);

  console.log(items);
  const userUid = user ? user.uid : null;

  const uploadImage = async () => {
    try {
      const uuid = uid();
      if (imageUpload == null) return;
      const imageRef = storageref(
        storage,
        `images/${uuid}   ${imageUpload.name}`
      );
      const uploadTask = uploadBytesResumable(imageRef, imageUpload);
      uploadTask.on(
        "state_changed",
        (snapshot) => {
          // progrss function ....
          const progress =
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
          setImageUploadDone("Upload is "   progress.toFixed()   "% done");
        },
        (error) => {
          // error function ....
          console.log(error);
        },
        () => {
          // complete function ....
          getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
            setImageUrl(downloadURL);
          });
        }
      );
    } catch (error) {
      throw error;
    }
  };

  const writeToDatabase = () => {
    const uuid = uid();
    const docRef = doc(storedb, "users", user.email);
    const colRef = collection(docRef, "items");
    addDoc(colRef, {
      uuid,
      category,
      contactnumber,
      description,
      price,
      sellername,
      title,
      userUid,
      imageurl,
    });
    setTitle("");
    setCategory("");
    setContactNumber("");
    setDescription("");
    setPrice("");
    setSellerName("");
    setImageUrl("");
  };

  const changeHandler = () => {
    writeToDatabase();
  };
  useEffect(() => {
    if (user) {
      console.log(user);
    }
    const docRef = doc(storedb, "users", "[email protected]");
    const docSnap = getDoc(docRef).then((doc) => {
      console.log(doc.data());
    });

    // const useremailref = collection(storedb, "users");
    // const q = query(useremailref, where("email", "==", user.email));
    // const getquery = getDocs(q).then((collection) => {
    //   setUserData(collection.docs.map((doc) => doc.data()));
    // });

    const itemsCollection = collectionGroup(storedb, "items");
    const data = getDocs(itemsCollection).then((collection) => {
      setItems(collection.docs.map((doc) => doc.data()));
    });
    console.log(items);
  }, []);

  return (
    <dataContext.Provider
      value={{
        category,
        setCategory,
        contactnumber,
        setContactNumber,
        description,
        setDescription,
        price,
        setPrice,
        sellername,
        setSellerName,
        title,
        setTitle,
        imageurl,
        setImageUrl,
        changeHandler,
        items,
        setImageUpload,
        uploadImage,
        setImageUploadDone,
        imageuploaddone,
        imageUpload,
        userdata,
      }}
    >
      {children}
    </dataContext.Provider>
  );
}

export function useDataContext() {
  return useContext(dataContext);
}

// import { useState, createContext, useContext } from "react";

// const dataContext = createContext();

// export function DataContextProvider({ children }) {
//   const data = "1245r1";

//   return (
//     <dataContext.Provider value={{ data }}>{children}</dataContext.Provider>
//   );
// }

// export function useDataContext() {
//   return useContext(dataContext);
// }

UserAuthContext.js :

import { createContext, useContext, useEffect, useState } from "react";
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  onAuthStateChanged,
  signOut,
  GoogleAuthProvider,
  signInWithPopup,
  sendEmailVerification,
} from "firebase/auth";
import { auth } from "../firebase";
import { storedb } from "../firebase";

const userAuthContext = createContext();

export function UserAuthContextProvider({ children }) {
  const [user, setUser] = useState({});

  function emailVerification() {
    return sendEmailVerification(auth.currentUser);
  }

  function logIn(email, password) {
    return signInWithEmailAndPassword(auth, email, password);
  }
  function signUp(email, password) {
    return createUserWithEmailAndPassword(auth, email, password);
  }
  function logOut() {
    return signOut(auth);
  }
  function googleSignIn() {
    const googleAuthProvider = new GoogleAuthProvider();
    return signInWithPopup(auth, googleAuthProvider);
  }

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentuser) => {
      // console.log("Auth", currentuser);
      setUser(currentuser);
    });

    return () => {
      unsubscribe();
    };
  }, []);

  return (
    <userAuthContext.Provider
      value={{ user, logIn, signUp, logOut, googleSignIn, emailVerification }}
    >
      {children}
    </userAuthContext.Provider>
  );
}

export function useUserAuth() {
  return useContext(userAuthContext);
}

App.js :

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { UserAuthContextProvider } from "./context/UserAuthContext";
import { DataContextProvider } from "./context/DataContext";
import { SearchContextProvider } from "./context/SearchContext";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <UserAuthContextProvider>
    <DataContextProvider>
      <SearchContextProvider>
        <App />
      </SearchContextProvider>
    </DataContextProvider>
  </UserAuthContextProvider>
);

CodePudding user response:

You have to add currentuser to dependency array, so when value of current user will change useEffect will be re-render and assign new value to user state

useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentuser) => {
      // console.log("Auth", currentuser);
      setUser(currentuser);
    });

    return () => {
      unsubscribe();
    };
  }, [currentuser]);
  • Related