I am trying to send users to different routes based on the roles of the user which is stored in the realtime firebase database, but I am getting the following error:
App.js:36 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'users')
Following is my App.js file where I am making the call for the firebase data"
App.js
`
import React from "react";
import { Route, Routes, Navigate } from "react-router-dom";
import Landing from "./components/Landing";
import PhoneDetails from "./components/PhoneDetails";
import Home from "./components/Home/App.jsx";
import Signup from "./components/Signup";
import SignIn from "./components/Signin";
import { auth } from "./firebase-config.js";
import { useEffect } from "react";
import FirebaseData from "./firebaseData";
function App() {
document.body.style = "background: #F8F5FA;";
// getting the user data from firebase
const firebaseData = FirebaseData();
const [displayName, setDisplayName] = React.useState("");
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [role, setRole] = React.useState("");
useEffect(() => {
auth.onAuthStateChanged((user) => {
if (user) {
// User is signed in
// ...
setIsAuthenticated(trEue);
setDisplayName(user.displayName);
// ERROR ON THIS LINE
setRole(firebaseData.users[user.uid].role)
// setRole(firebaseData.users[user.uid].role);
} else {
// User is signed out
// ...
setIsAuthenticated(false);
setDisplayName("");
setRole("");
}
});
}, []);
console.log("role:", role);
return (
<Routes>
<Route
path="/"
exact
element={
<Home isAuthenticated={isAuthenticated} displayName={displayName} role={role}/>
}
/>
<Route path="/signup" element={<Signup />} />
<Route path="/signin" element={<SignIn />} />
{
isAuthenticated && role === "admin" ? (
<Route path="/home" element={<Landing />} />
) : (
<Route
path="/"
element={
<Home isAuthenticated={isAuthenticated} displayName={displayName} />
}
/>
)
}
{isAuthenticated && role === "admin" ? (
<Route path="/details" element={<PhoneDetails />} />
) : (
<Route
path="/"
element={
<Home isAuthenticated={isAuthenticated} displayName={displayName} />
}
/>
)}
<Route path="/" element={<Navigate replace to="/" />} />
<Route path="*" element={<Navigate replace to="/" />} />
</Routes>
);
}
export default App;
`
In my App.js I am calling the FirebaseData() file which is given below:
firebaseData.js
`
import {database} from "./firebase-config";
import React from "react";
import {ref, onValue} from "firebase/database";
import {useEffect} from "react";
const db = database;
export default function FirebaseData() {
const [data, setData] = React.useState(null);
useEffect(() => {
onValue(ref(db), (snapshot) => {
setData(snapshot.val());
});
}, []);
return data;
}
`
The data in the firebase DB is stored in the following format:
users
—->uid
——>roles
I’ve tried to find the solution for this but couldn’t find any. Any help will be appreciated!
>Solution :
check firebaseData is defined in the useEffect and check if users exists using ? operator
useEffect(() => {
if(firebaseData){
auth.onAuthStateChanged((user) => {
if (user) {
// User is signed in
// ...
setIsAuthenticated(trEue);
setDisplayName(user.displayName);
// ERROR ON THIS LINE
setRole(firebaseData.users?.[user.uid]?.role)
// setRole(firebaseData.users[user.uid].role);
} else {
// User is signed out
// ...
setIsAuthenticated(false);
setDisplayName("");
setRole("");
}
});
}
}, [firebaseData]);