Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取未返回承诺的函数的返回值_Javascript_Firebase_Asynchronous_React Native_Promise - Fatal编程技术网

Javascript 获取未返回承诺的函数的返回值

Javascript 获取未返回承诺的函数的返回值,javascript,firebase,asynchronous,react-native,promise,Javascript,Firebase,Asynchronous,React Native,Promise,我正在将firebase api调用从react本机组件抽象到服务层。这对于返回承诺的调用很有效,但这一个调用onAuthStateChanged不会返回承诺。 如果没有服务层,我只需执行以下操作: firebase.auth().onAuthStateChanged(user => { if (user) { //logged in } else { //not logged in } 现在我想把所有东西都放在我的services/api.js中,我已经尝试了几种方法,但最新

我正在将firebase api调用从react本机组件抽象到服务层。这对于返回承诺的调用很有效,但这一个调用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,它不会等待它。
对于这个问题,什么是好的解决方案?

您可以围绕一个不支持承诺的呼叫创建一个承诺:

export const userLoggedIn = () => {
  return new Promise((resolve, reject) => {
    firebase.auth().onAuthStateChanged(user => {
      resolve(!!user);
    })
  });
}
尽管承诺适用于一次性检查,但身份验证状态可能在应用程序的生命周期内发生多次更改,例如,如果用户决定稍后注销。这样,您的应用程序可能会在firebase检查用户是否登录之前进行渲染,从而导致错误的身份验证检查,即使他们确实登录了

    if (userLoggedin()) {
    // logged in 
} else {
    // logged out
}
下面是我建议的方法:使用组件状态跟踪当前用户,以及当前是否正在检查身份验证状态

注意:这是可靠的,因为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 />
  }
}
从“React”导入React
从“firebase”导入firebase
类应用程序扩展了React.Component{
状态={
认证:正确,
用户:null,
}
componentDidMount(){
firebase.auth().onAuthStateChanged(用户=>{
this.setState({user,authenticating:false})
})
}
render(){
if(this.state.authentication){
//我们还在检查授权状态,
//例如,可能在此处呈现“登录…”加载屏幕
返回
}
if(this.state.user===null){
//未登录
返回
}
//在这里,身份验证检查完成,用户登录,正常渲染
返回
}
}

另外,请注意,如果您只想检查应用程序中的某个位置是否有用户当前登录,
firebase.auth().currentUser!==空值也可以。

您需要返回承诺并使用它。这是我第一次看到这个双重值!操作人员我必须查清楚它的意思。谢谢你教我新东西!你的回答对我有用。但是kingdaro提供的答案对于我的react原生项目来说更为充分,因此我将标记他的答案为正确。但是你的也帮助了我!啊,对不起,
,我用得太多了,以至于忘了它可能会让人困惑。无论如何,正如您可能已经发现的,它被用来将其转换为booleanTnx,这是一个伟大的解决方案!设法让它与尼古拉斯·塔尔斯的答案结合起来工作。也谢谢你提醒我关于当前用户的电话,完全忘记了那个!