【问题标题】:Firebase user is null after page refresh页面刷新后 Firebase 用户为空
【发布时间】:2019-07-04 16:13:09
【问题描述】:

当我第一次登录并使用我的 Web 应用程序时,我能够检索经过身份验证的用户并从数据库中访问该用户的信息。但是,一旦我刷新页面,我就会得到“TypeError:无法读取 null 的属性 'uid'”。

我能够对此进行一些调试,并看到当我最初登录时,我的身份验证组件(这是一个包装我的 App 组件的高阶组件)的 ComponentDidMount(),它通过以下方式检查经过身份验证的用户调用 onAuthStateChanged,在获取数据的组件的 ComponentDidMount() 之前调用。但是,当我刷新时,调用的顺序会切换,然后我的身份验证组件会被调用。我的最终目标是能够获取登录用户的 uid,以便从数据库中获取他们的数据。

下面是我的 withAuthentication 组件:

import React from 'react';

import AuthUserContext from './context';
import { withFirebase } from '../Firebase';

const withAuthentication = Component => {
  class WithAuthentication extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        authUser: null,
      };
    }

    componentDidMount() {
      this.listener = this.props.firebase.auth.onAuthStateChanged(
        authUser => {
          authUser
            ? this.setState({ authUser })
            : this.setState({ authUser: null });
        },
      );
    }

    componentWillUnmount() {
      this.listener();
    }

    render() {
      return (
        <AuthUserContext.Provider value={this.state.authUser}>
          <Component {...this.props} />
        </AuthUserContext.Provider>
      );
    }
   }

      return withFirebase(WithAuthentication);
    };

export default withAuthentication;

然后我使用这个高阶组件来包装我的根 App 组件,如下所示:

const App = () => (
  <Router>
    <Switch>
      {indexRoutes.map((prop, key) => {
        return <Route exact path={prop.path} component={prop.component} key= 
   {key} />;
          })}
        </Switch>
      </Router>
    );



export default withAuthentication(App);

这个根应用程序组件然后在我的根 index.js 文件中呈现

ReactDOM.render(
    <FirebaseContext.Provider value={new Firebase()}>
      <App />
    </FirebaseContext.Provider>,
  document.getElementById('root'),
);

【问题讨论】:

  • 请在codesandbox分享代码
  • 我认为正常的顺序是子组件的 ComponentDidMounts 比其父组件运行得早(这是合乎逻辑的,因为您不能说组件在其所有子组件都已安装之前已安装)。我不确定它如何与 HOC 一起使用,但可以相同。我建议将一些 isAuthed 布尔值传递给包装的组件,并在那里实现 getDerivedStateFromProps。当此 auth prop 变为 true 时,触发数据获取。
  • @UmairFarooq 刚刚添加到我的代码中

标签: reactjs firebase firebase-authentication


【解决方案1】:

这是因为当您登录时,首先authUser 为空,然后您登录并为authUser 分配用户对象,并在其他一些组件中使用authUser.uid,它运行良好。

下次重新加载页面时,登录页面不会打开,因为您已经登录,因此它会呈现使用authUser.uid 的其他组件。默认情况下authUser 为空,默认状态为nullonAuthStateChanged 是异步的,这意味着它不会立即执行,因此使用authUser.uid 的其他组件会出错。在您使用uid 的组件中,您可以执行以下操作,例如:

authUser ? authUser.uid : ''

【讨论】:

  • 假设我在使用 uid 的组件中执行此操作,一旦获取了经过身份验证的用户,我该如何获取数据?截至目前,如果我使用您的方法,authUser 将设置为 ' ' 并且不会重新更新。
  • 您可以使用firebase.auth().currentUser;。同样在 componentDidMount 中,请通过安慰检查 authUser 的值。如果值没问题,那么AuthUserContext.Consumer 中的用户值应该可用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 2017-02-21
  • 1970-01-01
  • 2019-07-20
相关资源
最近更新 更多