Я пытаюсь реализовать простую аутентификацию по электронной почте и паролю с помощью Firebase и React.
У меня есть firebase.js
файл, в котором я инициализирую соединение Firebase и экспортирую функцию auth
в виде переменной, например:
import firebase from 'firebase'
import 'firebase/auth'
import 'firebase/firestore'
const firebaseConfig = {
apiKey: <value>,
authDomain: <value>,
databaseURL: <value>,
projectId: <value>,
storageBucket: <value>,
messagingSenderId: <value>,
appId: <value>,
measurementId: <value>,
}
firebase.initializeApp(firebaseConfig)
const auth = firebase.auth()
const firestore = firebase.firestore()
export { auth, firestore }
Затем в компоненте App
(который является точкой входа в мое приложение) я использую auth
, чтобы наблюдать за изменениями в состоянии авторизации, вызывая onAuthStateChanged
:
const App = () => {
const [isAuthenticated, setIsAuthenticated] = useState()
useEffect(
() =>
auth.onAuthStateChanged((user) => {
if (user) {
console.log('authenticated in app component')
setIsAuthenticated(true)
} else {
console.log('not authenticated in app component')
setIsAuthenticated(false)
}
}),
[isAuthenticated]
)
if (isAuthenticated === undefined) return null
return (
<Router>
<Container maxWidth="sm">
<nav>
{isAuthenticated ? (
<Fragment>
<Link className={'nav-button'} to="/">
<Button>Home</Button>
<Button onClick={auth.signOut()}>Logout</Button>
</Link>
</Fragment>
) : (
<Link className={'nav-button'} to="/login">
<Button>Login</Button>
</Link>
)}
</nav>
<Switch>
<Route path="/login" component={Login} />
<PrivateRoute
exact
path="/"
component={Home}
authenticated={isAuthenticated}
/>
</Switch>
</Container>
</Router>
)
}
Наконец, у меня есть компонент Login
, который также отслеживает состояние авторизации и позволяет пользователю войти в систему с помощью электронной почты и пароля:
const Login = () => {
const [email, setEmail] = useState()
const [password, setPassword] = useState()
const [isAuthenticated, setIsAuthenticated] = useState()
useEffect(
() =>
auth.onAuthStateChanged((user) => {
if (user) {
console.log('authenticated in login component')
setIsAuthenticated(true)
} else {
console.log('not authenticated in login component')
setIsAuthenticated(false)
}
}),
[isAuthenticated]
)
const handleSubmit = () => {
auth
.signInWithEmailAndPassword(email, password)
.then(() => setIsAuthenticated(true))
.catch((error) => {
console.log(error)
})
}
if (isAuthenticated) return <Redirect to="/" />
<rendering the form etc>
Проблема заключается в том, что при успешном входе в систему я могу кратко увидеть что состояние аутентификации изменилось на аутентифицированное и что оно было поднято в обоих компонентах App
и Login
, но затем оно сразу же переходит обратно в состояние без аутентификации без каких-либо действий с моей стороны:
Я пробовал разные решения, отслеживая состояние авторизации с и без useEffect
ловушки, даже используя не рекомендуемое свойство auth().currentUser
, но ничего не работает - аутентификация соблазн не будет сохраняться Мне было интересно, имеет ли это какое-либо отношение к тому, как я инициализирую Firebase, ie могу ли я повторно инициализировать его несколько раз, не обращая внимания на то, что "сбрасывает" состояние аутентификации?
Любой совет, который высоко ценится.