How to connect your Angular application to Firebase
Tags: angular, firebase, javascript, typescript
Published: 2019-10-01 18:57:13

In this post, I will show you how you can connect your reactive form with Google Firebase. If you missed part 1 on how to make a reactive form, here is a link to it.

{% link https://dev.to/enniob/how-to-create-a-reactive-form-in-angular-2c1d %}

##Create your Firebase account

If you don’t have a Firebase account go to https://firebase.google.com/ and follow the steps on how to create your Firebase account. If you already have an account, log in to your account, and create a new project.

This should take a few seconds, and once done it should redirect you to a new page.

For now, that is all we need to do on Firebase, we will get back to it once we set up our application.

I create a starter repo that contains the basic setup for the project. So, let’s clone the repo.

```
git clone https://github.com/enniob/reactiveForms.git
```
Now that the repo is cloned, change to the following branch ***remotes/origin/Reactive-Form-Part-2***.

```
git checkout Reactive-Form-Part-2
```
Let’s take a look at the current state of the application. Open the console, and type `npm install` this will install all the dependencies needed. Once that is done, run `ng serve -o`.

You can see that our application has 2 pages; Home and login. If you click on login you will see a login form where you can enter a username and password. If you enter the login and password and click login, all we are doing is `console.log` the formData.

So now that we know our application is working, let’s connect our login form with Firebase.

We will use the AngularFire library to make the connections between your Angular project and Firebase.

First, let’s install AngularFire `npm install firebase @angular/fire --save`
 
Once the installation is done, we need to change `enviroment.ts` file to include the Firebase configuration for our application.

`enviroment.ts`

```
export const environment = {
  production: false,
  firebase: {
    apiKey: 'xxxxxxxxxxxxxxx',
    authDomain: 'xxxxxxxxxxxxxxx',
    databaseURL: 'xxxxxxxxxxxxxxx',
    projectId: 'xxxxxxxxxxxxxxx',
    storageBucket: 'xxxxxxxxxxxxxxx',
    messagingSenderId: 'xxxxxxxxxxxxxxx',
    appId: 'xxxxxxxxxxxxxxx'
  }
};
```
You can get that information from the firebase website, open your project and click on add app.

Open `app.module.ts` and import **AngularFireModule, and AngularFireAuthModule**. We also need to import our `environment.ts`.

`app.module.ts`
```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { environment } from '../environments/environment';

// MATERIAL
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { HomeComponent } from './home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    BrowserAnimationsModule,
    MatCardModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatToolbarModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```
Now open `login.component.ts` and let's add the following code, so we can connect our form with 

`login.component.ts`
```
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { FormGroup, FormControl, Validators } from '@angular/forms';
import { AngularFireAuth } from '@angular/fire/auth';

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

  loginForm = new FormGroup({
    userName: new FormControl('', Validators.compose([Validators.required])),
    password: new FormControl('', Validators.compose([Validators.required]))
  });

  constructor(private afAuth: AngularFireAuth, private router: Router) { }

  ngOnInit() {
  }

  doLogin(formData: FormGroup) {
    if (formData.valid) {
      this.afAuth.auth.signInWithEmailAndPassword(formData.value.userName, formData.value.password)
        .then(loginResponse => {
          console.log(loginResponse);
          this.router.navigate(['/']);
        })
        .catch(error => {
          console.log(error);
        });
    }
  }
}
```
As you can see on the code above, we imported `import { AngularFireAuth } from '@angular/fire/auth';` and that gives us access to the AngularFireAuth object where we can use the methods `signInWithEmailAndPassword` to login our user with a username and password. Just keep in mind that with FireBaseAuth you have many options for authentication, so make sure you use the method that you need for your authentication. You can see here the documentation of the available options (https://firebase.google.com/docs/reference/js/firebase.auth.Auth).

Now that we have our application connected to firebase, let run it and see what happens. Open your console and run `ng serve -o` after the application builds, it should open the browser with our application.

Open the developer console, and navigate to the login page. Once there enter a username and password. Notice the error on the console that error means that we do not have Firebase setup to authenticate users using email and password. To enable that, go to the firebase website and open your application. Now click on Authentication -> sign-in method.

Now click on Email/Password, select enable and click save. Click on the user tabs and add a new user. Once that is done, go back to your application and enter the username and password you created on the firebase website.

Notice now that on the developer console you do not see the error message anymore and you can see an object with user information and login type. That means that the user was authenticated.

Now open `home.component.ts` and add the following code. This code will check if the user is logged in or not.

`home.component.ts`
```
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.sass']
})
export class HomeComponent implements OnInit {
  userData = '';

  constructor(private afAuth: AngularFireAuth) { }

  ngOnInit() {
    this.afAuth.authState.subscribe(data => {
      if (data) {
        this.userData = data.email;
        console.log(data);
      }
    });
  }

  logoutUser() {
    this.afAuth.auth.signOut().then(response => {
      console.log(response);
      this.userData = '';
    })
    .catch(error => {
      console.log(error);
    });
  }
}
```
As you can see how our application is able to connect with Firebase Auth and validate the user credentials, also note that if the user closes the browser and comes back to your application it will check with Firebase if the user is already logged in and if they are it will display the welcome message. A few improvements we need to do is create a service for all the Firebase authentication function, so we can reuse the code throughout our application. On the next part, the starter repo will include a new service with all the authentication functions and we will add a check to make sure only registered users can access some routes on our application.

You can change to the branch `Reactive-Form-Part-2-Final` to view all the file changes we did.