Implementing Role-Based Authentication with Firebase in Your App
Tuesday, January 28, 2025
Managing user roles is crucial for many applications, especially when you need to control who can access specific features or sections of your app. In this guide, we'll walk through implementing role-based authentication using Firebase Authentication and Firestore. Whether you're building an admin dashboard or a multi-user platform, this method ensures secure and scalable role management.
Step 1: Set Up Firebase Authentication
Before we can assign and manage roles, we need Firebase Authentication up and running in our app.
Initialize Firebase
Enable Authentication
Step 2: Add Role Information to Firestore
Firestore will act as our database to store role-related information.
Set Up a Firestore Collection
Assign Roles to Users
import { doc, setDoc } from "firebase/firestore";
import { getFirestore } from "firebase/firestore";
const db = getFirestore(app);
const createUserWithRole = async (userId, role) => {
await setDoc(doc(db, "users", userId), {
role: role,
permissions: role === "admin" ? ["read", "write", "delete"] : ["read"],
});
};
Step 3: Retrieve Role Data in Your App
Once a user logs in, fetch their role from Firestore.
Set Up an Auth Listener
Use Firebase's onAuthStateChanged to detect when a user logs in:
import { onAuthStateChanged } from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
onAuthStateChanged(auth, async (user) => {
if (user) {
const userDoc = await getDoc(doc(db, "users", user.uid));
if (userDoc.exists()) {
const role = userDoc.data().role;
console.log("User role:", role);
}
}
});
Store the Role in State
Use React Context or Redux to manage user roles globally:
const [userRole, setUserRole] = useState("");
useEffect(() => {
if (user) {
const fetchRole = async () => {
const userDoc = await getDoc(doc(db, "users", user.uid));
setUserRole(userDoc.data().role);
};
fetchRole();
}
}, [user]);
Step 4: Enforce Role-Based Access in the Frontend
Conditional Rendering
Show or hide components based on the user's role.
Example:
if (userRole === "admin") {
return <AdminDashboard />;
} else {
return <Unauthorized />;
}
Restrict Routes
Use middleware to protect routes. Example with Next.js:
export default function AdminPage({ userRole }) {
if (userRole !== "admin") {
return <p>Unauthorized</p>;
}
return <AdminDashboard />;
}
Step 5: Secure Data with Firestore Rules
To ensure your database is secure, write Firestore rules that enforce role-based access.
Example rule to restrict access to admins:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId && resource.data.role == "admin";
}
}
}
Step 6: Testing and Debugging
Conclusion
Role-based authentication is an essential feature for any multi-user application. By leveraging Firebase Authentication and Firestore, you can manage roles securely and efficiently. Start implementing role-based authentication in your app today and scale your permissions model as your user base grows!