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]);