获取未返回promise的函数的返回值

时间:2018-03-16 17:30:50

标签: javascript firebase asynchronous react-native promise

我正在将我的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,并且它不会等待它。 什么是这个问题的好方法?

2 个答案:

答案 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也能正常工作。