Twitter LogoFacebook Logo
Project 1: Building a Social Media Site Part 4: Login System Part 1
The focus for this tutorial is to implement the functions for the Authenticator component.
By: King

To begin, open your project from where we left on in the previous video and then go to the Authenticator component TypeScript file. Import the FirebaseTSAuth class and create a FirebaseTSAuth object.

...
import { FirebaseTSAuth } from 'firebasets/firebasetsAuth/firebaseTSAuth';


@Component({
  selector: 'app-authenticator',
  templateUrl: './authenticator.component.html',
  styleUrls: ['./authenticator.component.css']
})
export class AuthenticatorComponent implements OnInit {
  ...

  firebasetsAuth: FirebaseTSAuth;

  constructor() { 
    this.firebasetsAuth = new FirebaseTSAuth();
  }

  ngOnInit(): void {
  }
  ...

}

The FirebaseTSAuth class contains functions to manage the Authentication part of Firebase. 


If we go to the Firebase console and look on the left side. There is a tab call Authentication. 

Image from Codeible.com

Click on it and you will see an interface with 4 tabs. You may have to click on a button call Get Started if you do not see this page. 

Image from Codeible.com

The Users tab will show us all the users that are registered for the app. 

The Sign-in method tab is where we set how the user can register and log into our app. By default, everything is set to disable so no one would be able to register or sign in.

Click on the Email/Password provider and enable it. 

If we want the user to be able to log in with their Google account, we would click on Google and enable it as well.

Image from Codeible.com

So right now, users can register for an account using an Email and password and also log in with that account or they can register and log in with a Google account. 

The Templates tab, is where we set the template for our emails that we send out. 

If we want our registered users to verify their email, we’ll run a function from the FirebaseTSAuth class and it’ll send an email to the user with this template.

Image from Codeible.com

The usage tab shows us how much resources we are using for Authetentication.

How your project is connected with Firebase

To remind you how our app is connected with Firebase, we imported the FirebaseTSApp class in the app module file and linked the project by calling the init function.

...

import { FirebaseTSApp } from 'firebasets/firebasetsApp/firebaseTSApp';


@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { 
  constructor(){
    FirebaseTSApp.init(environment.firebaseConfig);
  }
}

Modifying the Authenticator Component

Go to the Authenticator component HTML page and add a template reference for the 3 inputs in the register content.

1) Call the email input registerEmail. Use the hash symbol and then the name.
2) Call the password input registerPassword 
3) and the confirm password input registerConfirmPassword
4) Attach a click event to the register button and pass in the 3 template references.

<div *ngIf="isRegisterState()">
     <input #registerEmail placeholder="Email">
     <input #registerPassword
           placeholder="Password" type="password">
     <input #registerConfirmPassword 
           placeholder="Confirm Password" type="password">
     <button 
                (click)="onRegisterClick(
                    registerEmail,
                    registerPassword,
                    registerConfirmPassword
                )"
       mat-flat-button color="warn">Create</button>
</div>

Go to the Authenticator Component TypeScript file and define the function. For the type of each parameter, set it to HTMLInputElement since we are referencing input elements. 

Authenticator Component TypeScript

onRegisterClick(
    registerEmail: HTMLInputElement,
    registerPassword: HTMLInputElement,
    registerConfirmPassword: HTMLInputElement
  ){


}

Inside the function:

1) Get the value of each input.
2) Grab the FirebaseTSAuth object and call the createAccountWith() function. 

The function takes in a JSON object with up to 4 properties. The first 2 properties are for the email and password and the next 2 properties are for the callback functions onComplete and onFail.

onRegisterClick(
    registerEmailHTMLInputElement,
    registerPasswordHTMLInputElement,
    registerConfirmPasswordHTMLInputElement
  ){

    let email = registerEmail.value;
    let password = registerPassword.value;
    let confirmPassword = registerConfirmPassword.value;

    this.firebasetsAuth.createAccountWith(
       {
          email: email,
          password: password,
          onComplete: (uc) => {

          },
          onFail: (err) => {

          }
        });

}

The onFail() callback function gets triggered when it fails to create the account.  Call the alert function and print out a message when it fails.

The onComplete callback function gets triggered when it completes the transaction and creates the account. Call the alert() function in here as well and print out a message.

The email and password properties are the values that will be used to create the account. Replace the empty quotes with the email and password values from the inputs. 

this.firebasetsAuth.createAccountWith(
{
     email: email,
     password: password,
     onComplete: (uc) => {
            alert("Account Created");
            registerEmail.value = "";
            registerPassword.value = "";
            registerConfirmPassword.value = "";
     },
     onFail: (err) => {
           alert("Failed to create the account.");
     }
});

Create a function call isNotEmpty(). 

The purpose of this function is to check if a value is empty or not. 

1) Add a parameter call text with the type string.
2) For the return statement, check if it is not null and has a length greater than 0.

isNotEmpty(text: string){
    return text != null && text.length > 0;
}

Create another function call isAMatch(). 

This function will check if 2 strings are equal. 

1) Add 2 parameters to it to accept 2 string values.
2) For the return statement, check if both strings are equal.

isAMatch(text: string, comparedWith: string){
    return text == comparedWith;
}

Go back to the onRegisterClick() function and wrap the code to create the account with an if statement.

Inside the parenthesis, check if the all the inputs is not empty and then call the isAMatch() function to check if both password inputs are equal. 

onRegisterClick(
    registerEmail: HTMLInputElement,
    registerPassword: HTMLInputElement,
    registerConfirmPassword: HTMLInputElement
  ){

    let email = registerEmail.value;
    let password = registerPassword.value;
    let confirmPassword = registerConfirmPassword.value;

    if(
      this.isNotEmpty(email) &&
      this.isNotEmpty(password) && 
      this.isNotEmpty(confirmPassword) &&
      this.isAMatch(password, confirmPassword)
    ){
       this.firebasetsAuth.createAccountWith(
          {
             email: email,
             password: password,
             onComplete: (uc) => {
                alert("Account Created");
                registerEmail.value = "";
                registerPassword.value = "";
                registerConfirmPassword.value = "";
             },
             onFail: (err) => {
                alert("Failed to create the account.");
             }
           });
   }

}

If we run our app, we will be able to create an account with an email and password. 

1) Click on the Get Started button
2) Toggle the register content.
3) Enter a valid email and password and click register. 

If you typed everything right, we will get an popup that says the Account is created. 

Image from Codeible.com

If we go to the Firebase console and refresh the data for our users, our account will show up. 

Image from Codeible.com

Add Login Feature

Go to the Authenticator Component HTML page and add a template reference for the 2 inputs in the login content.

1) Call the email input loginEmail
2) Call the password input loginPassword
3) Attach an click event to the login button and pass in the 2 template references. 

<div *ngIf="isLoginState()">
     <input #loginEmail placeholder="Email"/>
     <input #loginPassword placeholder="Password" 
              type="password">
     <button 
        (click)="onLogin(loginEmail, loginPassword)"
        mat-flat-button color="warn">Login</button>
</div>

Go to the Authenticator Component TypeScript file and define the function. The type of the parameters, are also HTMLInputElements.

  onLogin(
    loginEmail: HTMLInputElement,
    loginPassword: HTMLInputElement
  ){
  

  }

Inside the function:


1) Get the values of the inputs
2) Use the if statement to check if both values are not empty 
3) Inside the if statement, grab the FirebaseTSAuth object and call the signInWith function

 let email = loginEmail.value;
 let password = loginPassword.value;

if(this.isNotEmpty(email) && 
    this.isNotEmpty(password)) {

    this.firebasetsAuth.signInWith();

}

The function takes in a JSON object with up to 5 properties but we just need 4.

The first 2 will be for the email and password.
The next 2 will be for the onComplete() and onFail() callback functions.

this.firebasetsAuth.signInWith(

   {
       email: email,
       password: password,
       onComplete: (uc) => {
           alert("Logged In");
       },
       onFail: (err) => {
           alert(err);
       }
   }
);

The onFail() callback function will get triggered when it fails to log in. Call the alert function and print out a message.

The onComplete() callback function gets triggered when it successfully logs in.  Call the alert function as well.

The email and password values are used as the credentials when logging in. Replace the empty quotes with the email and password values.

If we run the app, we will be able to log in. 

Image from Codeible.com

Adding Reset Password Feature

To add the feature for resetting the password, go back to the Authenticator Component HTML page and add a template reference for the email input. 


1) Call the input resetEmail. 
2) Then attach a click event to the reset button and pass in the reference.

<div *ngIf="isForgotPasswordState()">
   <input #resetEmail placeholder="Email">
   <button (click)="onResetClick(resetEmail)" 
         mat-flat-button color="warn">Reset</button>
</div>

Go to the Authenticator Component TypeScript file and define the function.

Inside the function:


1) Get the value of the email
2) Use the if statement to check if the value is not empty.

onResetClick(resetEmail: HTMLInputElement){
    let email = resetEmail.value;
    if(this.isNotEmpty(email)) {
    
    }
}

To reset the password, grab the FirebaseTSAuth object and call the sendPasswordResetEmail() function. 

onResetClick(resetEmail: HTMLInputElement){
    let email = resetEmail.value;
    if(this.isNotEmpty(email)) {

       this.firebasetsAuth.sendPasswordResetEmail();

    }
}

The function takes in a JSON object with up to 2 properties.

The first property it needs is the email and the second property is the onComplete() callback function.

this.firebasetsAuth.sendPasswordResetEmail(

   {
       email: email,
       onComplete: (err) => {
            alert(`Reset email sent to ${email}`);
       }
    }
);

The onComplete() callback function will get triggered at the end of the process even if it fails so keep that in mind. Add an alert() statement

The email property is the email that we want to send the instructions to.

Run the app on the browser and toggle the reset password content. Then enter the email for the account. 

Image from Codeible.com

When you see the alert popup, log in to the email and check your inbox.

Image from Codeible.com

You will see a noreply email from the project. 

Image from Codeible.com

Click on it and we will see the instructions to reset the password. If we click on the link, it will bring us to a page to reset the password.

Image from Codeible.com

Sign In