最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Handling firebase auth with react-router - Stack Overflow

programmeradmin0浏览0评论

I am building a React + Redux + Firebase app with webpack and am trying to figure out the best way to handle protected routes and redirects. I have tried using onEnter() with setTimeout() like many examples show, but it still ended up flashing the alternate ponent before redirecting.

Here is what I currently have, and I am trying to e up with a more elegant solution. This mostly works, but an example of when it fails is if I am on /profile and navigate to / in the browser. It seems that because firebase.auth() needs to initialize again, I get a flash of the HomePage ponent before it switches to Profile.

Firebase is initialized in firebaseClientConfig and I am passing firebase.auth() in to routes.

import { auth } from './firebaseClientConfig';  

...    

export default (
<Route path="/" ponent={App}>    
 <IndexRoute
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (!user) {
        return require.ensure([], require => {
          cb(null, require('./ponents/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>
);

Does anyone have a better way of doing this?

I am building a React + Redux + Firebase app with webpack and am trying to figure out the best way to handle protected routes and redirects. I have tried using onEnter() with setTimeout() like many examples show, but it still ended up flashing the alternate ponent before redirecting.

Here is what I currently have, and I am trying to e up with a more elegant solution. This mostly works, but an example of when it fails is if I am on /profile and navigate to / in the browser. It seems that because firebase.auth() needs to initialize again, I get a flash of the HomePage ponent before it switches to Profile.

Firebase is initialized in firebaseClientConfig and I am passing firebase.auth() in to routes.

import { auth } from './firebaseClientConfig';  

...    

export default (
<Route path="/" ponent={App}>    
 <IndexRoute
  getComponent={(nextState, cb) => {
    auth.onAuthStateChanged((user) => {
      if (!user) {
        return require.ensure([], require => {
          cb(null, require('./ponents/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>
);

Does anyone have a better way of doing this?

Share Improve this question asked Sep 6, 2016 at 0:41 BonitisBonitis 1531 gold badge3 silver badges9 bronze badges 4
  • 1 That's pretty elegant, nice! – Michael Bushe Commented Oct 19, 2016 at 7:50
  • @Bonitis I heard redux does not go well with firebase – ey dee ey em Commented Nov 1, 2017 at 15:31
  • @Ezeewei they actually work together beautifully! This question is outdated because react-router has gone from v3 -> v4, so there are major changes. In general, I have had no issues with redux+firebase. – Bonitis Commented Nov 2, 2017 at 12:56
  • @Bonitis ah nice! that's a really good news, myself was hesitating intergrating them together. thanks! – ey dee ey em Commented Nov 2, 2017 at 13:54
Add a ment  | 

3 Answers 3

Reset to default 4

I made a PrivateRoute ponent and pass it an authenticated prop which I get from the redux store in the ponent where I use the PrivateRoute

When I login with firebase I put user data in the redux store. So in my case i would map state to props

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

And give the authenticated prop to my PrivateRoute ponent

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

if you are managing authentication using local state instead of redux then you need to create two states to hold progress of your authentication.

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

i.e. redner Loading ponent initialy when loading is true and when i receive current user state from firebase function i will use setState() to set loading to flase and further render the ponent i intend to render according to the user state.

For better understanding have look react firebase authentication

I know is kind of late, but this might help others: You can find a slightly different approach here (still with a private route so kind of similar to vhflat but I find it a little more clear and easy to implement).

Basically, in your private route you just

import { useSelector } from "react-redux";

and

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

After that you get the auth like this

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

Then if the isLoaded( auth ) is not true (so the auth state is not loaded) you can redirect to a loading page or just return a <React.Fragment></React.Fragment> if you don't want.

In the end if on your return, you can check if !isEmpty( auth ), and if that is true return the children ponent, otherwise Redirect to the login page or any other page you prefer.

发布评论

评论列表(0)

  1. 暂无评论