使用react-router处理firebase auth

时间:2016-09-06 00:41:38

标签: javascript reactjs firebase react-router firebase-authentication

我正在使用webpack构建React + Redux + Firebase应用程序,并试图找出处理受保护路由和重定向的最佳方法。我尝试将onEnter()setTimeout()一起使用,就像许多示例所示,但它仍然会在重定向之前闪烁备用组件。

这是我目前拥有的,我正在努力想出一个更优雅的解决方案。这主要是有效的,但它失败的一个例子是我在/profile并在浏览器中导航到/。似乎因为firebase.auth()需要再次初始化,我会在切换到HomePage之前获得Profile组件的闪存。

Firebase在firebaseClientConfig初始化,我将firebase.auth()传递给routes

import { auth } from './firebaseClientConfig';  

...    

export default (
<Route path="/" component={App}>    
 <IndexRoute
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (!user) {
        return require.ensure([], require => {
          cb(null, require('./components/HomePage').default);
        });
      } else {
        return require.ensure([], require => {
          cb(null, require('./modules/Profile/Profile').default);
        });
      }
    });
  }}
/>
<Route
  path="/profile"
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (user) {
        return require.ensure([], require => {
          cb(null, require('./modules/Profile/Profile').default);
        });
      } else {
        return require.ensure([], require => {
          cb(null, require('./modules/Login/Login').default);
        });
      }
    });
  }}
/>
</Route>
);

有没有人有更好的方法呢?

3 个答案:

答案 0 :(得分:1)

我制作了一个PrivateRoute组件,并传递了一个authenticated道具,该道具是我在使用PrivateRoute的组件的redux存储中获得的

当我使用Firebase登录时,我将用户数据存储在redux存储中。所以在我的情况下,我会将状态映射到道具

const mapStateToProps = (state) => ({
    authenticated: !!state.user.uid,
})

并将经过身份验证的道具提供给我的PrivateRoute组件

const PrivateRoute = ({ component: Component, authenticated, path, exact }) => {
  return (
      <Route
          path={path}
          exact={exact}
          render={props =>
            authenticated
              ? <Component {...props} />
              : <Redirect to="/login"/>}
        />
    )
}

答案 1 :(得分:0)

如果您使用本地状态而不是redux管理身份验证,则需要创建两个状态来保存身份验证进度。

state={"loading=true",
"loggedin=false"}

即redner在加载为true时以及当我从firebase函数接收当前用户状态时加载组件初始状态时,我将使用setState()将加载设置为flase并进一步根据用户状态渲染我打算渲染的组件。

为更好地理解,请看react firebase authentication

答案 2 :(得分:0)

我知道有点晚了,但是这可能会对其他人有所帮助:您可以找到一种稍微不同的方法here(仍然使用类似于vhflat的私有路由,但是我发现它更加清晰和容易实施)。

基本上,在您的私人路线中,您只是

import { useSelector } from "react-redux";

import { isLoaded } from 'react-redux-firebase'

之后,您将获得这样的身份验证

const auth = useSelector( state => state.firebase.auth );

然后,如果isLoaded( auth )不正确(因此未加载身份验证状态),则可以重定向到加载页面,或者如果不需要的话,只返回<React.Fragment></React.Fragment>

最后,如果返回,则可以检查!isEmpty( auth )是否为真,如果返回true,则返回子组件,否则,重定向到登录页面或您喜欢的任何其他页面。