[英]How do I keep a user Logged in when refreshing a page with firebase authentication
Basically, I have a page that uses the user uid in a useEffect, but when I refresh the page the user is null and thus unable to get the uid on time.基本上,我有一个在 useEffect 中使用用户 uid 的页面,但是当我刷新页面时,用户是 null,因此无法按时获取 uid。
UserAuthContext code - this is where I do my login, signup and logout UserAuthContext 代码 - 这是我登录、注册和注销的地方
import {createContext, useContext, useEffect, useState} from 'react';
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
getAuth,
} from 'firebase/auth';
const userAuthContext = createContext();
export function UserAuthContextProvider({children}){
const [user, setUser] = useState(null);
const [userInfo, setUserInfo] = useState(null);
const auth = getAuth();
function signUp(email, password, isAdmin){
return createUserWithEmailAndPassword(auth, email, password);
}
function signIn(email, password){
return signInWithEmailAndPassword(auth, email, password);
}
function SignOut(){
signOut(auth).then(() => {
// Sign-out successful.
console.log("Sign-out successful");
setUser(null);
setUserInfo(null);
}).catch((error) => {
// An error happened.
});
}
useEffect(
() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) =>{
setUser(currentUser);
});
return unsubscribe();
},
[]
);
return <userAuthContext.Provider value={{user, userInfo, signUp, signIn, SignOut, setUser, setUserInfo}}>{children}</userAuthContext.Provider>
}
export function useUserAuth() {
return useContext(userAuthContext);
}
This is the page that needs the uid - user becomes null everytime I refresh the page这是需要 uid 的页面 - 每次我刷新页面时,用户都会变成 null
import Head from 'next/head'
import Navbar from '../../components/Navbar'
import Footer from '../../components/Footer';
import Link from 'next/link';
import Module from '../../components/Module';
import { addAssessment, addModule, modalState } from '../../atoms/modalAtom';
import { useRecoilState } from 'recoil';
import MyModal from '../../components/Modal';
import { collection, doc, getDoc, onSnapshot, query } from 'firebase/firestore';
import { db } from '../../firebase';
import { useEffect, useState } from 'react';
import { useUserAuth } from '../../context/UserAuthContext';
import DashboardSidebar from '../../components/DashboardSidebar';
export default function modules() {
const [isOpen, setIsOpen] = useRecoilState(modalState);
const [isAddModule, setIsAddModule] = useRecoilState(addModule);
const [isAddAssessment, setIsAddAssessment] = useRecoilState(addAssessment);
const [modules, setModules] = useState([]);
const {user, userInfo, setUser, setUserInfo} = useUserAuth();
// var modules = [];
// get modules form firebase
useEffect(
() =>
onSnapshot(
query(doc(db, "users", user.uid)),
(userSnapshot) => {
const userModules = userSnapshot.data().modules;
setUserInfo(userSnapshot.data());
if(userSnapshot.data().isAdmin){
onSnapshot(
query(collection(db, 'modules')),
(snapshot) => {
setModules(snapshot.docs);
}
)
}else{
userModules.forEach(userModule => {
getDoc(doc(db, 'modules', userModule)).then(moduleDoc => {
setModules(modules => [...modules, moduleDoc]);
});
});
}
}
),
[db]
)
return (
<div className="h-full">
<Head>
<title>My Uni Work</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<Navbar />
<div className="lg:flex space-x-0 h-full">
{/* sidebar area */}
<div>
<DashboardSidebar modules />
</div>
{/* content area */}
<div className="flex flex-col lg:px-10 mt-4 space-y-2 mb-6 w-full">
<div className="lg:flex m-2 items-center justify-between">
<p className="text-lg lg:text-2xl m-2 font-semibold text-[#333]">
Selected Modules
</p>
{userInfo?.isAdmin && (
<div className="flex flex-col lg:flex-row lg:items-center justify-end gap-1">
<button className="bg-[#103A5C] text-white font-semibold p-3 rounded-md hover:opacity-90
" onClick={(e) =>{
setIsOpen(true);
setIsAddModule(true);
}} >
Add Module
</button>
<button className="bg-[#103A5C] text-white font-semibold p-3 rounded-md hover:opacity-90
" onClick={(e) =>{
setIsOpen(true);
setIsAddAssessment(true);
}} >
Add assessment
</button>
</div>
)}
</div>
{/* <h1>{modules.length}</h1> */}
{modules.map(module =>(
<Module dashboardPage key={module.data().moduleCode} module={module.data()} />
))}
</div>
</div>
{/* Modal */}
{isOpen && <MyModal/>}
{/* <Footer /> */}
</div>
)
}
Store the user in Local Storage in the browser.将用户存储在浏览器的本地存储中。
Basically, whenever you are calling setUser() , do this instead:基本上,每当您调用setUser()时,请改为执行以下操作:
localStorage.setItem('user', *the variable which has the user data to be stored*)
To remove an item:要删除项目:
localStorage.removeItem('user')
To get said item in the future:要在将来获得所述项目:
localStorage.getItem('user')
If you share the code for the function signInWithEmailAndPassword() you've created I'll be able to provide further help.如果您共享您创建的 function signInWithEmailAndPassword()的代码,我将能够提供进一步的帮助。
Note: If storing a whole object, you need to deserialize it into a string first and whenever you need to use it again you need to serialize it back up.注意:如果存储一个完整的 object,则需要先将其反序列化为字符串,当需要再次使用时,需要将其序列化备份。 This is due to limitations with the Local Storage functionality.
这是由于本地存储功能的限制。
Use the function JSON.stringfy(*object variable*)
to deserialize.使用 function
JSON.stringfy(*object variable*)
进行反序列化。
Use the function JSON.parse(*object in format of string variable*)
to serialize.使用 function
JSON.parse(*object in format of string variable*)
进行序列化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.