我正在将我的firebase api调用从我的反应本机组件调用到服务层。这对于返回promise的调用很有效,但是这个调用onAuthStateChanged不会返回promise。 没有服务层,我会这样做:
firebase.auth().onAuthStateChanged(user => {
if (user) {
//logged in
} else { //not logged in }
现在我想将所有内容都放在我的services / api.js中,我已经尝试了几件事,但最新的是:
export const userLoggedin = () => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
return true
} else {
return false
}
})
}
然后在我的app.js中,我想检查userLoggedin是否返回true或false,因此我可以导航用户,具体取决于他是否已经登录。
if (userLoggedin()) {
// logged in
} else {
// logged out
}
现在这最后一部分总是会出现在else中,因为userLoggedin稍后会返回true,并且它不会等待它。 什么是这个问题的好方法?
答案 0 :(得分:2)
你可以围绕一个不支持承诺的电话创建一个承诺:
export const userLoggedIn = () => {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged(user => {
resolve(!!user);
})
});
}
答案 1 :(得分:1)
虽然承诺可以进行一次性检查,但如果用户决定稍后退出,则身份验证状态可能会在应用程序的生命周期内多次更改例。那,并且你的应用程序可能在firebase完成之前实际呈现,检查用户是否已登录,即使他们实际登录也会导致错误的身份验证。
这是我建议的方法:使用组件状态来跟踪当前用户,以及当前是否正在检查身份验证状态。
注意:这是可靠的,因为onAuthStateChanged
回调将始终至少触发一次。如果auth检查首先完成,则回调将在其附加后立即被调用。
import React from 'react'
import firebase from 'firebase'
class App extends React.Component {
state = {
authenticating: true,
user: null,
}
componentDidMount() {
firebase.auth().onAuthStateChanged(user => {
this.setState({ user, authenticating: false })
})
}
render() {
if (this.state.authenticating) {
// we're still checking the auth state,
// maybe render a "Logging in..." loading screen here for example
return <LoadingScreen />
}
if (this.state.user === null) {
// not logged in
return <Redirect to='login' />
}
// here, auth check is finished and user is logged in, render normally
return <AppContent />
}
}
另外,请注意,如果您只是想在应用中的某个位置检查用户当前是否已登录,firebase.auth().currentUser !== null
也能正常工作。