You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Angular Firebase Authentication Tutorial - Email Password Signup
Episode 7 written by Jeff DelaneyHealth Check: This lesson was last reviewed on and tested with these packages:
- Angular v4
- AngularFire2 v4
Update Notes: Breaking changes have been introduced since this video's original release. Find updated versions about Firebase User Auth.
Find an issue? Let's fix it
Email/Password authentication in Angular requires a few extra steps compared to OAuth or Anonymous Auth. In this lesson, we are using the AngularFire2 package to login and signup users with an email and password, as well provide reactive form validation. I highly recommend checking our full AngularFirebase Authentication series
Angular Firebase Authentication Series
Let’s start by generating the necessary components.
ng g service core/auth |
## Step 1: Enable Email/Password Auth in Firebase
Make sure to enable email/password auth in Firebase first.
Make sure to activate the email password provider in Firebase.
## Step 2: Updating the Auth Service
I will be building upon the AuthService from our previous OAuth tutorial. You can find the full auth service code on github.
Start by defining the authState in the constructor.
@Injectable() |
First, we need to define a new class for EmailPasswordCredentials
that has members for the email and password fields. Using this class will give you explicit control over the login process. In this case, we only need email and password strings. You might also extract this to its own class file, but I adding it directly to service for now.
auth.service.ts
export class EmailPasswordCredentials { |
You can see we use two separate functions for signup and login. When triggering the login
function from AngularFire2 it is necessary to pass the provider and methods as the second argument.
emailSignUp(credentials: EmailPasswordCredentials): firebase.Promise<FirebaseAuthState> { |
Step 3: Building the Reactive Login/Signup Form
Our goal is to create a form validation that can scale up in complexity as needed. At this point, we only need to validate the email and password, but your app might need to collect other complex information from users, such as a username, address, phone number, etc. The reactive form model used below is the best option for creating large forms with custom validators.
Angular Reactive Form Concepts
FormBuilder
An angular class for writing custom forms with less verbose code.FormGroup
The parent that holds the form controls. We can pass the form group values to the login or signup functions when the form is valid.FormControl
Controls are the individual inputs in the form, in this case email and password inputs.
How our Reactive Form Works
We call a function named buildForm
during the NgOnInit
lifecycle hook. This initializes the FormGroup, the FormControls, and their validation rules. It also triggers a function named onValueChange
, which will update our validation messages whenever the user changes the forms value. The nice thing about this approach is that it allows us to define the form and its validation has just a plain JavaScript object. The signup and login functions will triggered when the form is submitted.
It’s also worth noting that the Validators are related to HTML5 constraint validators. The patten validator uses regex to force a certain pattern, which is a password with at least one letter and one number in this example. You can create your own custom validators, but that’s a whole lesson on its own.
users/user-form.component.ts
This may seem like a lot of code, but it’s doing a lot. This component handles both signup, login, form validation, and password resetting.
import { Component, OnInit } from '@angular/core'; |
In the template, we bind the userForm object the HTML form. Now we can pass the form controls using the formControlName
attribute on input elements. They will automatically use the validation logic defined in the TypeScript. The errors messages can then be displayed anywhere in the template with a single piece code. Here’s what the full form will look like for the new user signup.
users/user-form.component.html
<form [formGroup]="userForm" *ngIf="newUser" (ngSubmit)="signup()"> |
Toggling between Login and Signup
Depending on the complexity of your signup process, you may want separate components and forms for Login and Signup. In this simple example, we are reusing the same form for both actions. We just use a boolean variable to toggle between the forms in the template with the *ngIf="newUser"
directive.
users/user-form.component.ts
newUser: boolean = true; |
Submitting the Form with ngSubmit
Angular needs to override the standard HTML form submit process with its own ngSubmit
event. You listen for the ngSubmit
event by adding it to the beginning of the form, which will fire one of the signup()
or login()
functions when the submit button is triggered. You just need to add a button with type=submit inside the form.
users/user-form.component.ts
signup(): void { |
users/user-form.component.html
<form [formGroup]="userForm" *ngIf="newUser" (ngSubmit)="signup()"> |
Bonus Step: Resetting the Password
Firebase has an email/password reset process built in, but it’s not integrated into the AngularFire2 package. In this section, we interact directly with the Firebase API to trigger the a password reset. This will email the existing user a link that they can follow to securely update their password.
auth.service.ts
import * as firebase from 'firebase'; |
user-form.component.ts
passReset: boolean = false; |
user-form.component.html
<p *ngIf="!passReset && userForm.controls.email.valid" (click)="resetPassword()">Reset Password for {{userForm.value.email}}</p> |