Cloud-Powered Apps with Angular & Firebase: Part II

Yann Mulonda
DailyJS
Published in
5 min readFeb 6, 2020

Setup Firebase Authentication on Angular App

This what my app demo after completing Part II

Now that we have set up our Angular web application with Firebase by adding configuration values, we first need to add authentication through the Firebase console.

Click on Authentication, then Set up Sign-in Method.

Let’s enable email and password authentication.

In the application module (app.modules.ts), import the AngularFireAuth module.

Next, let’s generate a login component that will provide a form for the user to sign up and log in. Run the following command:

ng g c login

And a profile component that will display the current user info in the application after a successful login:

ng g c profile

Once these new components are created, a login and profile folder will be created inside /src/app and both the login and profile component will be added automatically to the app.module.ts.

my app.module.ts

Next, modify the application routing module (app-routing.module.ts) and add the login and profile component at the root route. We want to display the login form at the root route of our application.

my app-routing.module.ts

Using Angular route guards

  • On the login route, I add the canActivate AuthGuard using the AngularFireAuthGuard and authGuardPipe property. This prevents the user from requesting the root page when already logged in and redirects back to the profile page.
...
const redirectToProfile = () => map(
user => user ? ['profile', (user as any).uid] : true
);
...
const routes: Routes = [
{
path: '',
component: LoginComponent,
canActivate: [AngularFireAuthGuard],
data: { authGuardPipe: redirectToProfile}
...
  • In case a user knows someone else’s user ID, they might be able to go to that route, and we want to prevent that. onlyAllowSelf pipe in my routing module prevents that. If a user tries to go to a URL with another user ID without properly signing out and logging in, onlyAllowSelf will redirect back to the profile page that pertains to the authenticated user.
...
const onlyAllowSelf = next => map(
user => (!!user && next.params.id == (user as any).uid) || ['']
);

const routes: Routes = [
...
{
path: 'profile/:id',
component: ProfileComponent,
canActivate: [AngularFireAuthGuard],
data: { authGuardPipe: onlyAllowSelf}
...

Login Component

I designed my login form based on Bootstrap forms, which are input-based components designed to collect users’ data. Used as a login, subscribe or contact form, all of them can be easily customized.

my login.component.html | signUp form screenshot

Also, when working with forms in Angular, be sure to import the forms module form Angular Forms in your app.module.ts.

Run your application using the npm start command and verify that the Login/sign-up form displays.

Feel free to use Bootstrap signup forms as a starting point.

Login | Sing Up

Now that we have a new form for inputting information, let’s add functionality to the simple form and create a user with Firebase.

login.component.html

my login.component.html

This copy of my login.component.html is a full build with a login and signup switch feature option.

In my form on my login.component.html bellow, I created a local template variable called form and assign it a value of ngForm. Because we are inputting the forms module, Angular will attach the NgForm directive to any form.

<form #form="ngForm">

This makes the NgForm object available in our view. Note that this isn’t the string NgForm, but rather the NgForm object. When the form is submitted, we want to call the onSubmit method. And as an argument, we pass in the local form variable.

<form #form="ngForm" (submit)="onSubmit(form)">

The next step is the add the ngModel directive to all of the inputs; like this:

<input type="text" name="firstName" ngModel>

This will create an association between the inputs and the ngForm object. By doing this, the value of the ngForm object will have a value property, which will be an object containing every input with a ngModel directive at these properties. The property names will correspond to the value of the name attribute.

Displaying error on the form

Firebase performs client-side validation for you and you can display whatever error message for the user on the form: invalid password or email error message. This is the section that displays error on my form:

...
<small class="form-text text-danger mb-4" *ngIf="error">
{{ error }}
</small>
...

login.component.ts

my login.component.ts

In the login.component.ts:

  • We first need to import the AngularFire auth service.
  • implement a method to create a user. Async, onSubmit, it will take in the ngForm.

We will first use the Firebase auth service to create a user with email and password. Let’s start the response and we will call the createUserWithEmailAndPassword method.

...
error: string;
async onSubmit(form: NgForm) {
this.error = null;
...
try {
if (this.isSignUp) {
resp = await this.afAuth.auth.createUserWithEmailAndPassword(
email, password
);
await resp.user.updateProfile(
{ displayName: `${firstName} ${lastName}` }
);
form.reset();
...
catch (error) {
...
}

We use email and the password and if there’s an error, we will simply log it out for now.

After creating the user with email and password, we will update the display name of the user profile. And we can call the updateProfile method on that user that we get back.

The form.reset() method clear the form if the user successfully signs up.

Start the application with “npm start”. create a test user and go to the authentication tab in your Firebase console to confirm that you have a current Firebase session and a test user was created successfully.

Also, go to your application tab in the developer tools under indexDB and you will see information about the current Firebase user.

Displaying error on the form

Let’s start by opening up the Developer Tools while the application is running and check for any error messages on the console. Now, if you try to log in without inputting any information. You’ll notice that Firebase is already performing client-side validation for you.

For Illustration, if you try to log in with the email only. It’s throwing an error indicating there is no password. A wrong password will get back an “invalid password” error message.

I’m displaying those error messages back to the user:

...
error: string;
async onSubmit(form: NgForm) {
this.error = null;
...
catch (error) {
console.log(error.message);
this.error = error.message;
}
...
}

Switching between a login and a signup form

A variable called “action” holds the types of string: “login or signup”. Its default string value is login. Two getters are used in our template:

IsLogin() returns true if the current action is Login.

IsSignUp() returns true if the current action is Signup.

At this point, if you have issues running your app and would live to review mine. Check my demo full code on my GitHub repo.

Next, I will show how to display the current user profile after logging into the application and add a logout or sign out feature.

Next:

Show user profil and sign out

--

--

Yann Mulonda
DailyJS
Writer for

Co-Founder & CIO @ITOT | DevOps | Senior Site Reliability Engineer @ICF󠁧󠁢󠁳󠁣󠁴 | "Learning is experience; everything else is just information!”