获取未返回承诺的函数的返回值
2018-03-16
528
我将我的 firebase api 调用从我的 react native 组件中抽象出来,放到一个服务层。这对于返回承诺的调用很有效,但这个调用 onAuthStateChanged 不会返回承诺。 如果没有服务层,我只会这样做:
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,并且它不会等待它。 这个问题有什么好的解决方案吗?
2个回答
您可以围绕不支持承诺的调用创建一个承诺:
export const userLoggedIn = () => {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged(user => {
resolve(!!user);
})
});
}
Nicholas Tower
2018-03-16
尽管承诺 适用于 一次性检查,但身份验证状态可能会在应用程序的生命周期内多次更改,例如,如果用户决定稍后退出。这样,您的应用程序可能会在 Firebase 检查完用户是否已登录之前实际呈现,从而导致身份验证检查错误,即使他们实际上已登录。
这是我建议的方法:使用组件状态来跟踪当前用户,以及当前是否正在检查身份验证状态。
注意:这是可靠的,因为
onAuthStateChanged
回调
始终
会触发至少一次。如果身份验证检查首先完成,则回调将在附加后立即被调用。
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
也可以正常工作。
kingdaro
2018-03-16