2

I been trying to integrate the react-redux-firebase with my react app. Everything is working except for the protected routes

I copied the code for private route from react-react-firebase.

This is the code for my private route

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { useSelector } from "react-redux";
import { isLoaded, isEmpty } from "react-redux-firebase";

// A wrapper for <Route> that redirects to the login
// screen if you're not yet authenticated or if auth is not
// yet loaded
function PrivateRoute({ children, ...rest }) {
  // FIXME: #27 Imp This is not working for some reason, you can still access the not accessible locations
  const auth = useSelector((state) => state.firebase.auth);
  console.log(auth);
  console.log("Empty?");
  console.log(isEmpty(auth));
  console.log("Load?");
  console.log(isLoaded(auth));
  return (
    <Route
      {...rest}
      render={({ location }) =>
        // FIXME: Here it even if it is false it is rendering the children for some reason
        isLoaded(auth) && !isEmpty(auth) ? (
          // auth.uid==undefined ? ( // Even this does not work
          children
        ) : (
          <Redirect
            to={{
              pathname: "/redirect/login",
              state: { from: location },
            }}
          />
        )
      }
    />
  );
}

export default PrivateRoute;

Even when the isEmpty is false, it is returning the children.

This is my reducer code.

import { combineReducers } from "redux";
import { firebaseReducer } from "react-redux-firebase";

export default combineReducers({
  firebase: firebaseReducer,

  // authReducer,
  // apiStatusReducer,
});

I been trying to solve it for the past 1 week and would love any help or hints on why it isn't working. Thanks for the help.

Edit:-

For some weird reason, even exchanging the children and redirect positions is also working.

<Route
      {...rest}
      render={({ location }) =>
        // FIXME: Here it even if it is false it is rendering the children for some reason
        isLoaded(auth) && isEmpty(auth) ? (
          // auth.uid==undefined ? ( // Even this does not work
          <Redirect
            to={{
              pathname: "/redirect/login",
              state: { from: location },
            }}
          />
        ) : (
          children
        )
      }
    />
Vikranth
  • 1,538
  • 1
  • 14
  • 23

2 Answers2

2

This is an open issue in the react-redux-firebase repo(Link to Issue) as of 16 Sept 2020. There is an ugly workaround for this issue provided by @zachlyoung

Normally, we would login in this way:

firebase.login(credentials).then(() => {
  props.history.push("/dashboard"); // Private Route
});

Instead of directly going to the private route, we update the auth again.

firebase.login(credentials).then(() => {
  firebase.reloadAuth().then(() => {
    props.history.push("/dashboard"); // Private Route
  });
});
Ashfaq nisar
  • 2,500
  • 1
  • 12
  • 22
0

you need to change the condition to be like this:

isLoaded(auth) && !isEmpty(auth)

because when the isLoaded is false, isEmpty will be true and when isLoaded is true, the isEmpty will be false, that's why your condition always applies the second expression.

AWIXOR
  • 406
  • 4
  • 15
  • After several trails and errors for some reason, irrelevant of if it is true or false, it is returning children. I have no clue why. – Vikranth Jun 29 '20 at 08:51
  • It can't return children when both `isLoaded` and `!isEmpty` are true, logically. – AWIXOR Jun 29 '20 at 14:16
  • Exactly, infact I tried putting directly true and false in there and both of them returned children. I thought the problem might be elsewhere but after changing the code a little bit and doing the checking of true or false not in return but outside return works. I have updated the code that works, but I have to provide login details twice before it gives me the next page. – Vikranth Jun 30 '20 at 01:34