Angular and Firebase Authentication: A Complete Guide
This tutorial will guide you through the process of setting up and implementing Firebase Authentication in an Angular project. Firebase Authentication provides a secure and easy way to manage user authentication in your application, including features such as email/password authentication, social media authentication, and user roles. By the end of this tutorial, you will have a fully functional authentication system in your Angular application using Firebase.
Introduction
What is Angular?
Angular is a popular JavaScript framework for building web applications. It allows developers to build dynamic and interactive web pages using a component-based architecture. Angular provides a wide range of features and tools that make it easy to develop scalable and maintainable applications.
What is Firebase Authentication?
Firebase Authentication is a service provided by Google Firebase that allows developers to easily add authentication functionality to their applications. It provides a secure way to authenticate users using email/password, social media logins, and more. Firebase Authentication also handles user management tasks such as user registration, password reset, and email verification.
Setting up Angular Project
Before we can start implementing Firebase Authentication in our Angular project, we need to set up the project itself. This involves installing the Angular CLI and creating a new Angular project. We will also need to add Firebase to our project.
Installing Angular CLI
To install the Angular CLI, open your terminal or command prompt and run the following command:
npm install -g @angular/cli
Creating a new Angular project
Once the Angular CLI is installed, we can create a new Angular project by running the following command:
ng new my-project
This will create a new directory called "my-project" with the basic structure of an Angular project.
Adding Firebase to the project
To add Firebase to our Angular project, we need to install the Firebase SDK. Run the following command in your terminal or command prompt:
npm install firebase
Now that we have our Angular project set up and Firebase installed, we can move on to implementing Firebase Authentication.
Firebase Authentication
In this section, we will configure Firebase Authentication in our Angular project and implement the necessary functionality for user sign up, sign in, sign out, and handling user authentication state.
Configuring Firebase Authentication
To configure Firebase Authentication, we need to create a new Firebase project and enable the Authentication service.
- Visit the Firebase Console and create a new project.
- Once the project is created, navigate to the "Authentication" section in the Firebase Console.
- Click on the "Sign-in method" tab and enable the desired authentication providers (e.g., email/password, Google, Facebook, etc.).
Implementing Sign Up functionality
To allow users to sign up for our application, we need to create a sign-up form and handle the form submission in our Angular project.
- In your Angular project, create a new component called "SignUp" using the Angular CLI:
ng generate component SignUp
- Open the "sign-up.component.html" file and add the following form:
<form (ngSubmit)="onSubmit()">
<input type="email" [(ngModel)]="email" name="email" placeholder="Email" required>
<input type="password" [(ngModel)]="password" name="password" placeholder="Password" required>
<button type="submit">Sign Up</button>
</form>
- In the "sign-up.component.ts" file, add the following code:
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-sign-up',
templateUrl: './sign-up.component.html',
styleUrls: ['./sign-up.component.css']
})
export class SignUpComponent {
email: string;
password: string;
constructor(private afAuth: AngularFireAuth) {}
onSubmit() {
this.afAuth.createUserWithEmailAndPassword(this.email, this.password)
.then((userCredential) => {
// Handle successful sign up
})
.catch((error) => {
// Handle error
});
}
}
In this code, we import the AngularFireAuth
module from @angular/fire/auth
and inject it into our component. In the onSubmit()
method, we use the createUserWithEmailAndPassword()
method to create a new user with the provided email and password.
Implementing Sign In functionality
To allow users to sign in to our application, we need to create a sign-in form and handle the form submission in our Angular project.
- In your Angular project, create a new component called "SignIn" using the Angular CLI:
ng generate component SignIn
- Open the "sign-in.component.html" file and add the following form:
<form (ngSubmit)="onSubmit()">
<input type="email" [(ngModel)]="email" name="email" placeholder="Email" required>
<input type="password" [(ngModel)]="password" name="password" placeholder="Password" required>
<button type="submit">Sign In</button>
</form>
- In the "sign-in.component.ts" file, add the following code:
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-sign-in',
templateUrl: './sign-in.component.html',
styleUrls: ['./sign-in.component.css']
})
export class SignInComponent {
email: string;
password: string;
constructor(private afAuth: AngularFireAuth) {}
onSubmit() {
this.afAuth.signInWithEmailAndPassword(this.email, this.password)
.then((userCredential) => {
// Handle successful sign in
})
.catch((error) => {
// Handle error
});
}
}
In this code, we import the AngularFireAuth
module from @angular/fire/auth
and inject it into our component. In the onSubmit()
method, we use the signInWithEmailAndPassword()
method to sign in the user with the provided email and password.
Implementing Sign Out functionality
To allow users to sign out of our application, we need to create a sign-out button and handle the sign-out action in our Angular project.
- In your Angular project, open the "app.component.html" file and add the following button:
<button (click)="signOut()">Sign Out</button>
- In the "app.component.ts" file, add the following code:
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private afAuth: AngularFireAuth) {}
signOut() {
this.afAuth.signOut()
.then(() => {
// Handle successful sign out
})
.catch((error) => {
// Handle error
});
}
}
In this code, we import the AngularFireAuth
module from @angular/fire/auth
and inject it into our component. In the signOut()
method, we use the signOut()
method to sign out the currently authenticated user.
Handling User Authentication State
To handle the user authentication state in our Angular project, we can use the authState
observable provided by Firebase Authentication.
- In your Angular project, open the "app.component.ts" file and add the following code:
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
user: Observable<firebase.User>;
constructor(private afAuth: AngularFireAuth) {
this.user = afAuth.authState;
}
}
In this code, we import the AngularFireAuth
module from @angular/fire/auth
and inject it into our component. We also import the Observable
class from rxjs
to handle the asynchronous nature of the authState
observable. In the constructor, we assign the authState
observable to the user
property.
Additional Authentication Features
In addition to the basic sign up, sign in, and sign out functionality, Firebase Authentication provides additional features such as resetting passwords, email verification, social media authentication, securing Angular routes, and handling user roles.
Resetting Password
To allow users to reset their passwords, we can use the sendPasswordResetEmail()
method provided by Firebase Authentication.
- In your Angular project, create a new component called "ResetPassword" using the Angular CLI:
ng generate component ResetPassword
- Open the "reset-password.component.html" file and add the following form:
<form (ngSubmit)="onSubmit()">
<input type="email" [(ngModel)]="email" name="email" placeholder="Email" required>
<button type="submit">Reset Password</button>
</form>
- In the "reset-password.component.ts" file, add the following code:
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-reset-password',
templateUrl: './reset-password.component.html',
styleUrls: ['./reset-password.component.css']
})
export class ResetPasswordComponent {
email: string;
constructor(private afAuth: AngularFireAuth) {}
onSubmit() {
this.afAuth.sendPasswordResetEmail(this.email)
.then(() => {
// Handle successful password reset email
})
.catch((error) => {
// Handle error
});
}
}
In this code, we import the AngularFireAuth
module from @angular/fire/auth
and inject it into our component. In the onSubmit()
method, we use the sendPasswordResetEmail()
method to send a password reset email to the user with the provided email.
Email Verification
To verify user email addresses, we can use the sendEmailVerification()
method provided by Firebase Authentication.
- In your Angular project, open the "sign-up.component.ts" file and add the following code to the
onSubmit()
method:
onSubmit() {
this.afAuth.createUserWithEmailAndPassword(this.email, this.password)
.then((userCredential) => {
userCredential.user.sendEmailVerification();
// Handle successful sign up
})
.catch((error) => {
// Handle error
});
}
In this code, we call the sendEmailVerification()
method on the user
object returned by the createUserWithEmailAndPassword()
method to send a verification email to the user.
Social Media Authentication
Firebase Authentication supports social media logins such as Google, Facebook, Twitter, and more. To implement social media authentication in our Angular project, we need to enable the desired authentication providers in the Firebase Console and use the corresponding methods provided by Firebase Authentication.
- In your Angular project, open the "sign-in.component.ts" file and add the following code to the
onSubmit()
method:
onSubmit() {
this.afAuth.signInWithPopup(new firebase.auth.GoogleAuthProvider())
.then((userCredential) => {
// Handle successful sign in
})
.catch((error) => {
// Handle error
});
}
In this code, we use the signInWithPopup()
method with the GoogleAuthProvider
to sign in the user using their Google account. You can replace GoogleAuthProvider
with the desired provider (e.g., FacebookAuthProvider
, TwitterAuthProvider
, etc.).
Securing Angular Routes
To secure certain routes in our Angular application and restrict access to authenticated users, we can use route guards provided by Angular.
Implementing Route Guards
- In your Angular project, create a new service called "AuthGuard" using the Angular CLI:
ng generate service AuthGuard
- Open the "auth-guard.service.ts" file and add the following code:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private afAuth: AngularFireAuth, private router: Router) {}
canActivate(): Observable<boolean> {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
return true;
} else {
this.router.navigate(['/sign-in']);
return false;
}
})
);
}
}
In this code, we import the CanActivate
interface and the Router
module from @angular/router
, the AngularFireAuth
module from @angular/fire/auth
, and the Observable
and map
operators from rxjs
. We then implement the CanActivate
interface and define the canActivate()
method. In this method, we use the authState
observable to check if the user is authenticated. If the user is authenticated, we return true
to allow access to the route. If the user is not authenticated, we navigate the user to the sign-in page and return false
.
Restricting Access to Authenticated Users
To restrict access to certain routes in our Angular application to only authenticated users, we can use the canActivate
property in the route configuration.
- In your Angular project, open the "app-routing.module.ts" file and add the following code:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './auth-guard.service';
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
// ...
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
In this code, we import the Routes
and RouterModule
modules from @angular/router
and the AuthGuard
service we created earlier. We define our routes and use the canActivate
property to specify that the route can only be accessed by authenticated users.
Handling User Roles
To handle user roles in our Angular application, we can create user roles and restrict access to certain routes based on those roles.
Creating User Roles
- In your Angular project, create a new service called "RoleService" using the Angular CLI:
ng generate service RoleService
- Open the "role.service.ts" file and add the following code:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RoleService {
private roles: string[] = [];
constructor() {}
getRoles(): string[] {
return this.roles;
}
setRoles(roles: string[]): void {
this.roles = roles;
}
hasRole(role: string): boolean {
return this.roles.includes(role);
}
}
In this code, we create a RoleService
with methods to get the user roles, set the user roles, and check if the user has a specific role.
Restricting Access based on User Roles
To restrict access to certain routes based on user roles, we can modify the canActivate
method in our AuthGuard
service.
- In your Angular project, open the "auth-guard.service.ts" file and modify the
canActivate()
method as follows:
canActivate(): Observable<boolean> {
return this.afAuth.authState.pipe(
map((user) => {
if (user) {
const roles = this.roleService.getRoles();
if (roles.includes('admin')) {
return true;
} else {
this.router.navigate(['/access-denied']);
return false;
}
} else {
this.router.navigate(['/sign-in']);
return false;
}
})
);
}
In this code, we import the RoleService
and inject it into our AuthGuard
service. We then check if the user has the "admin" role before allowing access to the route. If the user does not have the "admin" role, they will be redirected to the "access-denied" page.
Conclusion
In this tutorial, we have learned how to set up and implement Firebase Authentication in an Angular project. We have covered the basics of Firebase Authentication, including sign up, sign in, and sign out functionality, as well as additional features such as resetting passwords, email verification, social media authentication, securing routes, and handling user roles. By following the steps in this tutorial, you should now have a solid foundation for implementing user authentication in your Angular applications using Firebase Authentication.