-1

What I want to achieve

display components based on user authority admin/!admin

//Everyone can see this login/register/reset

//Admin x paths

//regular users y paths

I have been having issues finding tutorials that explain properly step by step what I want to achieve I want to have an admin that has access to a different view than the other users, however the only video I found is not only outdated but in vue (Firebase Auth Tutorial) and not in react and I wasn't able to "translate" the code at some point to react so I got stuck it was about Custom Claims (is like 4 videos, there are more but the ones that explain the auth stuff was 17-21) I try to understand it but it was too complex for me also try to get into Firebase Security to try and see if I could do the admin thing but unsuccessful with that as well however someone mention well then what if you just simply add a value "isAdmin" in your firebase and set it up to true to w/e is gonna be admin and then anyone else when they register is false well that sounds simple.

Basically I want this view (Only this) for the admin which basically they can see all users orders with details:

enter image description here

While users can create/edit/delete "students" (their kids basically) and they can also create and view/edit/delete their own orders

enter image description here

FULL CODE, based on sugestion For some reason I can't do ANYTHING after trying this so I'm open to other suggestions

import React, { useEffect, useState } from "react";
import "./App.css";
import Register from "./Register";
import { auth, db } from "./firebase";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
import Login from "./Login.js";
import Inicio from "./Inicio";
import Reset from "./Reset";
import CrearEstudiante from "./CrearEstudiante";
import Estudiantes from "./ListadoEstudiantes"
import Pedidos from "./ListadoPedidos"
import CrearPedidos from "./CrearPedidos";
import AgregarLibro from "./AgregarLibro";
import AgregarAIB from "./AgregarAIB";
import AgregarOpcionales from "./AgregarOpcionales";
import Comprar from "./Comprar";
import VerPedidos from "./VerPedidos";
import UpdateProfile from "./UpdateProfile";
import EditForm from "./EditForm";
import DBLibros from "./DBLibros";
import DBDiccionarios from "./DBDiccionarios";
import DBLocal from "./DBLocal";

function App() {

  const [user, setUser] = useState([]);
  const [isAdmin, setIsAdmin] = useState(false);

  useEffect(() => {
    auth.onAuthStateChanged((authUser) => {

      if (authUser) {
        setUser(authUser);
      } else {
        setUser(false);
      }
    })
  }, [user])

  useEffect(() => {
    const userDoc = db.collection('usuarios').doc(user.uid);
    userDoc.get().then(doc => {
        if (doc.exists) {
            const tempData = [];
            const data = doc.data();
            tempData.push(data);
            setIsAdmin(tempData[0].isAdmin)
        }
      });
 }, [user])

 useEffect(() => {
  if(isAdmin === true){
    console.log("I'm an admin")
    console.log(isAdmin)
    console.log(user.uid)
  }
  else {
    console.log("No admin")
    console.log(isAdmin)
    console.log(user.uid)
  }
 }, [isAdmin])

  return (
    < div className="app" >
        <Router>
        <Switch>

        {isAdmin && (
            <>
          <Route path = "/Agregar_Libros">
            <Inicio user={user}/>
            <AgregarLibro />
          </Route>

          <Route path = "/Agregar_AIB">
            <Inicio user={user}/>
            <AgregarAIB />
          </Route>

          <Route path = "/Agregar_Opcional">
            <Inicio user={user}/>
            <AgregarOpcionales />
          </Route>

          <Route path = "/DB_Libros">
            <Inicio user={user}/>
            <DBLibros />
          </Route>

          <Route path = "/DB_Diccionarios">
            <Inicio user={user}/>
            <DBDiccionarios />
          </Route>

          <Route path = "/DB_Local">
            <Inicio user={user}/>
            <DBLocal />
          </Route>
          </>
          )}
          
          {!isAdmin && (
            <>
          <Route path = "/Inicio">
            <Inicio user={user}/>
            <Estudiantes user={user} />
            <Pedidos user={user} />
          </Route>

          <Route path = "/Profile">
            <Inicio user={user}/>
            <UpdateProfile user={user}/>
          </Route>

          <Route path = "/Editar_Estudiante">
            <Inicio user={user}/>
            <EditForm user={user}/>
          </Route>

          <Route path = "/Crear_Estudiante">
            <Inicio user={user}/>
            <CrearEstudiante user={user}/>
          </Route>

          <Route path = "/Crear_Pedidos">
            <Inicio user={user}/>
            <CrearPedidos user={user}/>
          </Route>
          
          <Route path = "/Comprar">
            <Inicio user={user}/>
            <Comprar user={user}/>
          </Route>

          <Route path = "/Ver_Pedidos">
            <Inicio user={user}/>
            <VerPedidos user={user}/>
          </Route>
          </>
          )}
          
          <Route path = "/Register">
            <Register/>
          </Route>

          <Route path = "/Reset">
            <Reset />
          </Route>

          <Route path = "/">
            <Login/>
          </Route>

        </Switch>
        </Router>
      </div >
  );
}
export default App;

When I have it like this I can't see the Register, Reset or Login ( in this case Path = "/") it pretty much depends in the order in which I have set up the routes which is weird.

ReactPotato
  • 1,262
  • 3
  • 26
  • 46

3 Answers3

2

This is typically done by using logical operators and ternaries. In your case, a logical AND operator should work:

return (
    < div >
      < div className="app" >
        <Router>
        <Switch>

          //Admin 
          /*
          {isAdmin && (
            <>
              <Route path = "/Agregar_Libro">
                <Inicio user={user}/>
                <AgregarLibro />
              </Route>

              ....
            </>
          )}
          */

          //Anyone since you are LogOut 
          /*
          <Route path = "/Register">
            <Register/>
          </Route>
          
          <Route path = "/Reset">
            <Reset />
          </Route> 

          <Route path = "/">
            <Login/>
          </Route>
           */

          //Users
          /*
          {!isAdmin && (
            <>
              <Route path = "/Inicio">
                <Inicio user={user}/>
                <Estudiantes user={user} />
                <Pedidos user={user} />
              </Route>
              
              ....
            </>
          )}
          */

        </Switch>
        </Router>
      </div >
    </div >
  );
}

export default App;
hayavuk
  • 351
  • 2
  • 6
  • yes this bit should help me with the part of separating based on isAdmin or not, however this doesn't tell me why is always returning !isAdmin – ReactPotato Oct 21 '21 at 23:22
  • That I don't know. Based on the title of your question, I thought this was your main trouble. Sorry. – hayavuk Oct 21 '21 at 23:26
  • I think leaving the other 3 outside doesn't help cause I can't see them regardless of if I'm admin or not – ReactPotato Oct 22 '21 at 00:03
  • Then you probably have more than one problem. Hard to say without seeing the entire code base, and how you use your app. – hayavuk Oct 22 '21 at 00:06
  • that's the entire code in the app.js is just the 2 pieces of code I added – ReactPotato Oct 22 '21 at 00:07
  • I think your usage of `useEffect()` is a bit wrong. The hooks are not used to organize code or define order of execution. They are simply a mechanism to react to a change in component state. You want to move all your code into a single hook. You also do not want the hook to depend on state that you are setting in your hook. Try that and it will probably start working. – hayavuk Oct 22 '21 at 00:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238416/discussion-between-hayavuk-and-reactpotato). – hayavuk Oct 22 '21 at 00:12
  • is there a way to say if admin = null in those kinds of statements ? – ReactPotato Oct 22 '21 at 00:50
0

What I'd recommend doing is implementing components that take care of rendering conditionally depending on the permissions you have.

For example

const CheckIsAdmin = ({children})=>{
  const permissions = useUserPermissions()
  
  if(permissions === "admin"){
  
    return <>{children}</>
  }
  
  return <> You don't have permissions for this</>
}
0

First of all, this will create an infinite loop of checking the user I guess.

 useEffect(() => {
    auth.onAuthStateChanged((authUser) => {

      if (authUser) {
        setUser(authUser);
      } else {
        setUser(false);
      }
    })
  }, [user]) //  Don't need to provide "user" here.

and for your question, How to restrict access to routes in react-router? Check the answer from this link and that'll give you an idea perhaps.

Silambarasan R
  • 1,346
  • 15
  • 22