Angular Firebase

An Angular Firebase App

Creating a new firebase project

I created a firebase project using https://console.firebase.google.com

haddley-firebase

disable google analytics

wait

firebase project has been created

Web

App nickname

Firebase SDK

firebase config
         
// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "AIzaSyBwvxBCAtDqHw4WrDnU4rMnecwx5wE3O1E",
  authDomain: "haddley-firebase-e8e21.firebaseapp.com",
  projectId: "haddley-firebase-e8e21",
  storageBucket: "haddley-firebase-e8e21.appspot.com",
  messagingSenderId: "2336199603",
  appId: "1:2336199603:web:52d6e29d9b05aa4005b1c6"
};

firebase project dashboard

Get started

Email/Password

Email/Password enable

esp8266

Creating a new angular project

I installed the Angular command line interface using npm

% npm i -g @angular/cli

I created a new Angular project using "ng new"

% ng new haddley-angular

ng new haddley-angular

npm start

http://localhost:4200

angular fire

https://www.npmjs.com/package/@angular/fire

npm i @angular/fire

npm i @angular/fire

environments

I added firebaseConfig to environments.ts

environments.ts

I added provideFirebaseApp, provideFirestore, provideAuth and ReactiveFormsModule to app.module.ts

login, register and dashboard components

ng generate component login
ng generate component register
ng generate component dashboard

ng generate component login, register and dashboard

I removed the sample html from app.component.html

bootstrap 5

I used bootstrap for styling the forms

CSS stylesheet link

CSS stylesheet link added

example form

register.component.html

register.component.ts
         
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Auth, createUserWithEmailAndPassword } from '@angular/fire/auth';
import { Router } from '@angular/router';

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss']
})
export class RegisterComponent implements OnInit {
  registerForm!: FormGroup;

  constructor(private formBuilder: FormBuilder, private auth: Auth, private router: Router) {
    this.registerForm = this.formBuilder.group({
      email: formBuilder.control('', [Validators.required, Validators.email]),
      password: formBuilder.control('', [Validators.required, Validators.minLength(6)]),
    })
  }

  public onSubmit(): void {
    createUserWithEmailAndPassword(this.auth, this.registerForm.value.email, this.registerForm.value.password)
      .then((res: any) => {
        console.log(res);
        this.router.navigate(['/login']);
      })
      .catch((err: any) => console.log(err));
  }

  ngOnInit(): void {
  }

}

login.component.html

login.component.ts
         
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Auth, signInWithEmailAndPassword } from '@angular/fire/auth';
import { Router } from '@angular/router';

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

  constructor(private formBuilder: FormBuilder, private auth: Auth, private router: Router) {
    this.loginForm = this.formBuilder.group({
      email: formBuilder.control('', [Validators.required, Validators.email]),
      password: formBuilder.control('', [Validators.required, Validators.minLength(6)]),
    })
  }

  public onSubmit(): void {
    signInWithEmailAndPassword(this.auth, this.loginForm.value.email, this.loginForm.value.password)
      .then((res: any) => 
      {
        console.log(res);
        this.router.navigate(['/dashboard']);
      })
      .catch((err: any) => console.log(err));
  }


  ngOnInit(): void {
  }

}

dashboard.component.html

dashboard.component.ts
         
import { Component, OnInit } from '@angular/core';
import { Auth } from '@angular/fire/auth';

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

  user = this.auth.currentUser;

  constructor(private auth: Auth) { }

  ngOnInit(): void {
    console.log(this.auth.currentUser);
  }

}

Route

Angular routing configuration

authguard.ts

app-routing.module.ts

firebase users (none)

/register

firebase users

/login

/dashboard

ng deploy

I used "ng deploy" to deploy the app.

% ng deploy

ng deploy

Saving and retrieving private message documents

addDoc and query collection

dashboard.component.html
         
<div class="container my-5">

    <p>dashboard works!</p>

    <div *ngIf="user">
        User {{ user.email }} is logged in.
    </div>

    <ul>
        <li *ngFor="let message of messages$ | async">
          {{ message.text }}
        </li>
      </ul>

    <form [formGroup]="createMessageForm" (ngSubmit)="onSubmit()">
        <div class="mb-3">
            <label for="exampleInputMessage1" class="form-label">Message</label>
            <input type="text" class="form-control" id="exampleMessage1" aria-describedby="messageHelp"
                formControlName="message">
            <div id="messageHelp" class="form-text">Enter message here.</div>
        </div>
        <button type="submit" class="btn btn-primary">Save</button>
    </form>
</div>
dashboard.component.ts
         
import { Component, OnInit } from '@angular/core';
import { Auth } from '@angular/fire/auth';
import { Firestore, addDoc, collection, collectionData, getFirestore, query, serverTimestamp, where } from '@angular/fire/firestore';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';

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

  user = this.auth.currentUser;
  createMessageForm!: FormGroup;
  messages$: Observable<any[]>;

  constructor(private formBuilder: FormBuilder, private auth: Auth, firestore: Firestore) {
    this.createMessageForm = this.formBuilder.group({
      message: formBuilder.control('', [Validators.required, Validators.minLength(6)])
    })
    const uid = this.auth.currentUser?.uid;
    const result = query(collection(firestore, 'messages'), where("uid", "==", uid));
    console.log(result);
    this.messages$ = collectionData(result);
  }

  ngOnInit(): void {
    console.log(this.auth.currentUser);
  }

  public onSubmit(): void {
    this.saveMessage(this.createMessageForm.value.message)
    this.createMessageForm.reset();
  }

  // Saves a new message to Cloud Firestore.
  private async saveMessage(messageText: string) {
    try {
      const uid = this.auth.currentUser?.uid;
      await addDoc(collection(getFirestore(), 'messages'), {
        uid: uid,
        email: this.auth.currentUser?.email,
        text: messageText,
        timestamp: serverTimestamp()
      });
    }
    catch (error) {
      console.error('Error writing new message to Firebase Database', error);
    }
  }

}

rules

dashboard