大家好, 我正在进行反应测试,我想在我的登录组件中实现 firebase 身份验证持久性。我知道您需要为此使用 setPersistence,但由于某种原因,身份验证在重新启动后不会保留。一般来说,我的身份验证和注册工作正常(我有几个组件 - Register.jsx 、 Login.jsx 和 Form.jsx 作为注册和登录的基础。只是当页面重新加载时,身份验证将重置为之前,没有任何错误。我的应用程序中也有 redux-toolkit。你能帮助我吗?我做错了什么?
这是我的base.js 文件:
import firebase from 'firebase/compat/app';
import { getDatabase } from 'firebase/database';
import 'firebase/compat/auth';
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
};
const app = firebase.initializeApp(firebaseConfig);
const database = getDatabase(app);
export default app;
这是我的登录组件:
import { Form } from './Form';
import { useDispatch } from 'react-redux';
import { setUser } from '../store/slices/userSlice';
import {
getAuth,
setPersistence,
signInWithEmailAndPassword,
browserSessionPersistence,
} from 'firebase/auth';
import { useNavigate } from 'react-router-dom';
const Login = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const auth = getAuth();
const handleLogin = async (email, password) => {
try {
await setPersistence(auth, browserSessionPersistence);
signInWithEmailAndPassword(auth, email, password).then(({ user }) => {
console.log(user);
dispatch(
setUser({
email: user.email,
id: user.uid,
token: user.accessToken,
})
);
navigate('/');
});
} catch (error) {
console.error('Invalid email or password', error);
}
};
return <Form title='sign in' handleClick={handleLogin} />;
};
export { Login };
您共享的代码仅处理用户主动登录的时刻,即当他们第一次输入凭据时。
当您重新加载页面时,Firebase 实际上会恢复用户之前输入的凭据,但您共享的代码无法处理这种情况。要获取恢复的用户,请使用
onAuthStateChanged
,如有关获取活动用户的文档中第一个代码示例所示:
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/auth.user
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
在您的Firebase配置文件中,从firebase / auth导入browserLocalPersistence和initializeAuth,定义导出的变量auth并为其分配initializeAuth的值与您的应用程序和一个空对象作为第二个参数,在空对象内创建一个密钥,持久性,并给它一个值 browserLocalPersistence。
import { getApps, initializeApp } from "firebase/app";
import { browserLocalPersistence, initializeAuth } from "firebase/auth";
const firebaseConfig = {...};
export const firebaseApp =
getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
export const auth = initializeAuth(firebaseApp, {
persistence: browserLocalPersistence,
});
现在,稍后当调用signInWithEmailAndPassword时,Firebase将根据传递给initializeAuth的选项对象指定的持久化类型持久化返回的数据。此外,如果您希望 Firebase Auth 使用多种持久性类型,请将持久性键的值设置为数组并将持久性类型包含到该数组中。
import {
signInWithCredential,
GoogleAuthProvider,
setPersistence,
browserLocalPersistence,
} from "firebase/auth";
import { auth } from "../lib/firebase/config";
import { useNavigate } from "react-router-dom";
const SignInPage = () => {
const navigate = useNavigate;
const handleClick = async () => {
try {
const authResponse = await chrome.runtime.sendMessage({
action: "invokeFirebaseAuth",
});
const credential = GoogleAuthProvider.credentialFromResult(
authResponse.credentials
);
signInWithCredential(auth, credential)
.then((userCredential) => {
const user = userCredential.user;
})
.catch((error) =>
console.error(
"There was an error signing in with credentials: ",
error
)
);
} catch (error) {
console.error(error);
}
};
return (
<div id={"sign-in-page"}>
<div style={{ margin: "20px 0" }}>
<button onClick={handleClick}> Firebase Auth</button>
</div>
</div>
);
};
export default SignInPage;
您可以在此处查看对此进行解释的文档。