ccc

Despliegue: Pasarlo a Producción

En la consola:
ng build --configuration production --aot Si no lo vamos a publicar en la raiz del hosting entonces habrá que especificar la subcarpeta donde se va a almacenar:
ng build --configuration production --aot --base-href /empleados
Ahora conectar con la BBDD de Firebase:
npm install -g firebase-tools Una vez instalado tienes q estar lógicamente logueado con tu cuenta de google con la q creaste antes la BBDD:
firebase login
Y una vez identificada tu cuenta de Google:
firebase init

Moverte con los cursores y seleccionar (con la barra espaciadora) las opciones de: Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys

Una vez marcados esos dos darle a intro.
En el siguiente paso elegir: Use an existing project y seleccionar la BBDD que hayamos usado

What do you want to use as your public directory? Escribir dist

Configure as a single-page app: Escribir Y

Set up automatic builds and deploys with GitHub: Escribir N

En Visual Studio Code en firebase.json en hosting->public escribir la ruta de nuestra APP:
"public": "dist/empleados-app",
Desde la consola de VSC:
firebase deploy
Una vez hecho el deploy ya nos dará las URLs para poder usarlos, por ejemplo:
Project Console: https://console.firebase.google.com/project/pruebaclientes-xxxab/overview
Hosting URL: https://pruebaclientes-xxxab.web.app

Guardianes para bloquear el acceso a algunas rutas

Creamos el fichero src\app\login\login-guardian.ts: import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from "@angular/router";
import { Observable } from "rxjs";
import { LoginService } from "./login.service";

@Injectable()
export class LoginGuardian implements CanActivate {

constructor(private loginService:LoginService, private router:Router) {
}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.loginService.estaLogueado()) {
return true;
}
else {
this.router.navigate(['login']);
return false;
}
}
}

En el src\app\app.module.ts registrarlo:
providers: [...,LoginGuardian]

Y ya tb en src\app\app.module.ts específicar a qué ruta queremos aplicarlos:
{path:'contacto', component:ContactoComponentComponent, canActivate:[LoginGuardian]},

Cookies

Desde la consola:
npm install ngx-cookie-service --save --force

En src\app\app.module.ts: import { CookieService } from 'ngx-cookie-service';
...
providers: [...,CookieService],

En el ts del servicio donde vayamos a usarlo:
constructor(...,private cookies:CookieService) {}
Y ya para almacenar datos en una cookie:
this.cookies.set("var1","loquesea);
Y para rescatarlo:
this.cookies.get("var1");

Login

En la consola de firebase:
1. Crear un usuario de pruebas para loguearte en Authentication -> Crear usuario

2. En Realtime Database -> Reglas imponer que tanto para leer como escribir en la BBDD haya que estar logueado:
".read": "auth!=null",
".write": "auth!=null",
Si se quiere leer/escribir siempre sin necesidad de loguear pues poner directamente true

3. En Configuración -> Configuración del proyecto -> General: hay que registrar la APP y ponerle un nombre (por ejemplo: com.lsg.empleados) para así obtener el ApiKey y el authDomain.

4. Instalar en VSCode el módulo de cookies: https://programando-angular.blogspot.com/2022/12/cookies.html

5. En src\app\app.component.ts en el ngOnInit:
firebase.initializeApp({
   apiKey: "AIzaxxxxx3qVcKrXkaK_doD334",
   authDomain: "com.lsg.empleados"
});

Crear un componente Login

Crear un loginService:
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import firebase from "firebase/compat/app";
import 'firebase/compat/auth';
import { CookieService } from "ngx-cookie-service";

@Injectable()
export class LoginService {
   constructor(private router:Router,private cookies:CookieService) {
}

token:string;

checkLogin(email:string,pw:string) {
   firebase.auth().signInWithEmailAndPassword(email,pw).then(
     response=>{
       firebase.auth().currentUser?.getIdToken().then(
       token => {
       this.token = token;
       this.cookies.set("token",this.token);
       this.router.navigate(['/']);
     }
   )
}
);
}

getTokenId() {
   return return this.cookies.get("token");
}

estaLogueado() {
   return this.cookies.get("token");
}

logout() {
   firebase.auth().signOut().then(
   ()=>{
   this.token = "";
   this.cookies.set("token",this.token);
   this.router.navigate(['/']);
   window.location.reload();
   }
   );
   }
}

En el constructor de src\app\data.services.ts añadir este servicio:
constructor(private httpClient:HttpClient, private loginService:LoginService) {}
En el html del componente Login: <form #formLogin="ngForm" (ngSubmit)="login(formLogin);" style="margin-top:20px;">
<input type="email" name="email" placeholder="email" ngModel>
<input type="password" name="pw" placeholder="Contraseña" ngModel>
<button type="submit">Aceptar</button>
</form>

El el ts del componente login:
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { LoginService } from './login.service';

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

constructor(private loginService:LoginService) { }

ngOnInit(): void {
}

login(form:NgForm) {
const email = form.value.email;
const pw = form.value.pw;

this.loginService.checkLogin(email,pw);
}
}

Para poner los links en de login y logout en la navbar hay que hacerlo en el componente principal app en src\app\app.component.html:
<li *ngIf="!checkIfLogged()"><a routerLink="/login">Login</a></li>
<li *ngIf="checkIfLogged()"><a (click)="logout()" style="cursor:pointer;">Logout</a></li>

Y en src\app\app.component.ts:
checkIfLogged() {
   return this.loginService.estaLogueado();
}

logout() {
   return this.loginService.logout();
}

Instalar Firebase en tu proyecto angular

Desde la consola:
npm install firebase
Si diese error al instalar probar con:
npm install --save firebase

Si da error de caché sucia:
npm install --save firebase --allow-dirty --force

Abrir el bloc de notas como Administrador y editar los ficheros npm, npm.cmd, npx y npx.cmd de C:\Program Files\nodejs cambiando:
prefix -g
Por:
prefix --location=global
En src\app\app.component.ts:
import firebase from 'firebase/compat/app';

Firebase: modificar y borrar un registro

MODIFICAR
En el src\app\data.services.ts:
updateEmpleado(indice:number,empleadoAux:Empleado) {
   let url = 'https://pruebaclientes-a8fab-default-rtdb.europe-west1.firebasedatabase.app/datos/'+indice+'.json';
   this.httpClient.put(url,empleadoAux).subscribe({
     next: (v) => console.log('Se ha actualizado ' + v),
     error: (e) => console.log('Error' + e),
   });
}

En el ts del servicio:
updateEmpleado(indice:number,empleadoAux:Empleado) {
   this.arrEmpleados[indice] = empleadoAux;
   // actualizarlo en la BBDD
   this.dataService.updateEmpleado(indice,empleadoAux);
}

Y ya desde el ts del componente:
...
this.servicioDosAux.updateEmpleado(this.indice,empleadoAux);
...

BORRAR
En el src\app\data.services.ts:
deleteEmpleadoBD(indice:number) {
   let url = 'https://pruebaclientes-a8fab-default-rtdb.europe-west1.firebasedatabase.app/datos/'+indice+'.json';
   this.httpClient.delete(url).subscribe({
      next: (v) => console.log('Se ha borrado ' + v),
      error: (e) => console.log('Error' + e),
   });
}

En el ts del servicio:
deleteEmpleado(indice:number) {
   this.arrEmpleados.splice(indice,1);
   // borrarlo de la BBDD
   this.dataService.deleteEmpleadoBD(indice);
  if (this.arrEmpleados!=null) {
      this.dataService.storeEmpleados(this.arrEmpleados);
   }
}

Y ya desde el ts del componente:
...
this.servicioDosAux.deleteEmpleado(this.indice);
...

Firebase: Obtener datos de la BBDD

En src\app\data.services.ts:
getEmpleadosFromBD() {
   return this.httpClient.get('https://pruebaclientes-a8fab-default-rtdb.europe-west1.firebasedatabase.app/datos.json');
}

En el ts del servicio:
arrEmpleados:Empleado[]=[];
...
getEmpleados() {
   return this.dataService.getEmpleadosFromBD();
}

// rellenar el array con los datos de la BBDD
fillEmpleados(empleadosAux:Empleado[]) {
   this.arrEmpleados = empleadosAux;
}

Y ya desde el ts del componente llamar a ese servicio (por ejemplo en el ngOnInit):
// empleadosAux será la var donde se almacene
this.servicioDosAux.getEmpleados().subscribe(empleadosAux=>{
   console.log(empleadosAux);
   // meterlo en nuestro array
   this.arrEmpleados = Object.values(empleadosAux);
   this.servicioDosAux.fillEmpleados(this.arrEmpleados);
});