U ovom ću blog postu napraviti primjer Angular web aplikacije koja će se sastojati od nekoliko ekrana. Glavna svrha ove web aplikacije je omogućiti korisnicima da se registriraju tj. prijave kako bi ju mogli koristiti. To će moći učiniti koristeći e-mail, Google ili Facebook korisnički račun.
Nekoliko sam blog postova već objavio na ovu temu, ali svi su bili vezani uz Ionic Framework. Iako je Ionic temeljen na Angularu shvaćam da osobama koje se tek susreću sa ovim može biti teže napraviti Angular projekt proučavajući Ionic sintaksu. Zato ovaj put radim čisti Angular web projekt.
Postavljanje Firebase projekta
Na adresi https://console.firebase.google.com/ kreiram novi Firebase projekt pod nazivom ‘AngularWebFirebase’.

Na sljedećem ekranu, klikom na ‘Add Firebase to your web app‘ dobijem objekt koji će mi biti potreban kako bi sve funkcioniralo. Taj ću objekt kasnije ugraditi unutar app.module.ts datoteke.

Nakon postavljanja projekta u izborniku Authentication odabirem Email/Password, Facebook i Google metodu registracije/prijave.

Kao što se može vidjeti iz slike iznad, Facebook prijava ne može se ugraditi bez dva parametra koja je moguće dobiti jedino na adresi https://developers.facebook.com/ gdje je potrebno kreirati profil za AngularWebFirebase aplikaciju.
Implementacija Firebase u Angular
Koristeći Angular CLI kreiram novi projekt.
|
$ ng new AngularWebFirebase $ cd AngularWebFirebase |
Sljedećom naredbom instaliram potreban NPM paket
|
$ npm install angularfire2 firebase --save |
Također, kao što sam ranije već spomenuo, u datoteku app.module.ts postavljam potreban Firebase objekt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuthModule } from 'angularfire2/auth'; export const firebaseConfig = { apiKey: "***************************************", authDomain: "***********************.firebaseapp.com", databaseURL: "https://***********************.firebaseio.com", projectId: "***********************", storageBucket: "***********************.appspot.com", messagingSenderId: "************" }; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule, HttpModule, AngularFireModule.initializeApp(firebaseConfig), AngularFireAuthModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
Sada ću kreirati četiri komponente od kojih će se sastojati moja Angular web aplikacija:
1 – LoginComponent – stranica za prijavu koristeći Facebook ili Google
2 – EmailComponent – stranica za prijavu koristeći e-mail
3 – SignupComponent – stranica za registraciju
4 – DashboardComponent – početna stranica nakon uspješne prijave
|
$ ng generate component login $ ng generate component email $ ng generate component signup $ ng generate component dashboard |
Ako sada pokrenem aplikaciju naredbom
$ ng serve na adresi http://localhost:4200/ mogu vidjeti jedino standardnu Angular početnu stranicu.

S obzirom da ja u ovom slučaju želim vidjeti svoju Login komponentu kao početnu stranicu moram napraviti sljedeće. Unutar /src/app/ kreiram datoteku app.routes.ts sa sljedećim sadržajem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
import { ModuleWithProviders } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { SignupComponent } from './signup/signup.component'; import { EmailComponent } from './email/email.component'; export const router: Routes = [ { path: '', redirectTo: 'login', pathMatch: 'full' }, { path: 'login', component: LoginComponent }, { path: 'signup', component: SignupComponent }, { path: 'email', component: EmailComponent }, { path: 'dashboard', component: DashboardComponent} ] export const routes: ModuleWithProviders = RouterModule.forRoot(router); |
Naravno, tu još ide uvoz u app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
import { AngularFireModule } from 'angularfire2'; import { AngularFireAuthModule } from 'angularfire2/auth'; import { LoginComponent } from './login/login.component'; import { EmailComponent } from './email/email.component'; import { SignupComponent } from './signup/signup.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { routes } from './app.routes'; ... declarations: [ AppComponent, LoginComponent, EmailComponent, SignupComponent, DashboardComponent ], imports: [ BrowserModule, FormsModule, HttpModule, AngularFireModule.initializeApp(firebaseConfig), AngularFireAuthModule, routes ], ... |
I nakon toga unutar datoteke app.component.html umjesto postojećeg sadržaja staviti
<router-outlet></router-outlet>.
Login komponenta
Nalazi se na adresi http://localhost:4200/login i to je zadani pregled koji se pojavi prilikom prve posjete web aplikaciji.

Ekran se sastoji od tri gumba. Facebook, Google i E-mail prijava uz mogućnost registracije.
|
<div class="form-container"> <img src="assets/images/login.png" id="login"> <span class="error" *ngIf="error">{{ error }}</span> <button (click)="loginFb()" id="fb">Login with Facebook</button><br> <button (click)="loginGoogle()" id="google">Login with Google</button> <button routerLink="/email" id="email">Login with E-mail</button> <a routerLink="/signup" routerLinkActive="active" class="alc">Don't have an account?</a> </div> |
Gumb za prijavu putem Facebooka ili Googlea pozivaju funkciju dok klik ma gumb za prijavu putem e-maila otvara novu stranicu na kojoj se nalazi forma za unos e-maila i lozinke.
Ako prijava putem Facebooka ili Googlea prođe zapisujem podatke o korisniku (name, picture, email) u localStorage kako bi ih kasnije mogao prikazati na Dashboardu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
import { Component, OnInit } from '@angular/core'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Router } from '@angular/router'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { error: any; constructor(public _angularAuth: AngularFireAuth, private _router: Router) { } ngOnInit() { } loginGoogle(){ let a = this; //this._angularAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()); firebase.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider()) .then(function(authData) { console.log(authData); if(authData.credential.accessToken){ localStorage.setItem('name', authData.additionalUserInfo.profile.name); localStorage.setItem('picture', authData.additionalUserInfo.profile.picture); localStorage.setItem('email', authData.additionalUserInfo.profile.email); a._router.navigate(['/dashboard']); } }).catch(function(error) { console.log(error); a.error = error.message; }); } loginFb(){ let a = this; //this._angularAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider()); firebase.auth().signInWithPopup(new firebase.auth.FacebookAuthProvider()) .then(function(authData) { console.log(authData); if(authData.credential.accessToken){ localStorage.setItem('name', authData.additionalUserInfo.profile.name); localStorage.setItem('picture', authData.additionalUserInfo.profile.picture.data.url); localStorage.setItem('email', authData.additionalUserInfo.profile.email); a._router.navigate(['/dashboard']); } }).catch(function(error) { console.log(error); a.error = error.message; }); } } |
Ovisno o postavkama unutar Firebasea jedan korisnik se (ne)može prijaviti koristeći istu e-mail adresu na različitim društvenim mrežama tj. ako se korisnik jednom prijavio koristeći Google, a kasnije se želi prijaviti koristeći Facebook dobiti će sljedeću poruku:

Ta se opcija može promijeniti klikom na ‘One account per email address‘.

Signup komponenta
Nalazi se na adresi http://localhost:4200/signup i osnovna svrha ovog ekrana je omogućiti korisnicima registraciju.

Ekran se sastoji od dva polja za unos e-maila i lozinke.
|
<div class="form-container"> <a routerLink="/login" id="goback">Go back</a> <h2>Registration</h2> <span class="error" *ngIf="error">{{ error }}</span> <form #formData='ngForm' (ngSubmit)="onSubmit(formData)"> <input type="text" placeholder="E-mail" (ngModel)="email" name="email" class="txt" required> <input type="password" placeholder="Password" (ngModel)="password" name="password" class="txt" required> <button type="submit" [disabled]="!formData.valid" class="basic-btn">Create my account</button> </form> </div> |
Ako registracija prođe u redu korisnik automatski bude preusmjeren na stranicu za prijavu. U suprotnom iznad polja za unos e-maila prikazuje se poruka o grešci.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
import { Component, OnInit } from '@angular/core'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Router } from '@angular/router'; @Component({ selector: 'app-signup', templateUrl: './signup.component.html', styleUrls: ['./signup.component.css'] }) export class SignupComponent implements OnInit { error: any; constructor(public _angularAuth: AngularFireAuth, private _router: Router) { } ngOnInit() { } onSubmit(formData) { let a = this; if(formData.valid) { console.log(formData.value); firebase.auth().createUserWithEmailAndPassword(formData.value.email, formData.value.password) .then(function(data) { console.log(data); if(data){ a._router.navigate(['/email']); } }).catch(function(error) { console.log(error); a.error = error.message; }); } } } |
Email komponenta
Nalazi se na adresi http://localhost:4200/email s osnovnom svrhom omogućavanja prijave korisnika pomoću e-maila i lozinke.

Ekran se sastoji od dva polja za unos e-maila i lozinke.
|
<div class="form-container"> <a routerLink="/login" id="goback">Go back</a> <h2>E-mail Login</h2> <span class="error" *ngIf="error">{{ error }}</span> <form #formData='ngForm' (ngSubmit)="onSubmit(formData)"> <input type="text" placeholder="E-mail" (ngModel)="email" name="email" class="txt" required> <input type="password" placeholder="Password" (ngModel)="password" name="password" class="txt" required> <button type="submit" [disabled]="!formData.valid" class="basic-btn">Log in</button> <a routerLink="/signup" class="alc">Don't have an account?</a> </form> </div> |
Unosom ispravnih podataka za prijavu korisnik automatski bude preusmjeren na Dashboard dok u suprotnom dobije poruku o grešci.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
import { Component, OnInit } from '@angular/core'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Router } from '@angular/router'; @Component({ selector: 'app-email', templateUrl: './email.component.html', styleUrls: ['./email.component.css'] }) export class EmailComponent implements OnInit { error: any; constructor(public _angularAuth: AngularFireAuth, private _router: Router) { } ngOnInit() { } onSubmit(formData) { let a = this; firebase.auth().signInWithEmailAndPassword(formData.value.email, formData.value.password) .then(function(data) { console.log(data); if(data){ localStorage.setItem('email', data.email); a._router.navigate(['/dashboard']); } }).catch(function(error) { console.log(error); a.error = error.message; }); } } |
Dashboard komponenta
Nalazi se na adresi http://localhost:4200/dashboard s osnovnom svrhom prikaza podataka o korisniku nakon uspješne prijave. U ovom slučaju prikazuje se ime i prezime korisnika, e-mail adresa i slika.

Na ekranu se mogu vidjeti podaci o korisniku pod uvjetom (*ngIf) da postoje.
|
<div class="form-container" id="toolbar"> <header> <button (click)="logout()" class="basic-btn">Logout</button> </header> <div id="page"> <h2 *ngIf="name">Hey {{name}}!</h2> <h6 *ngIf="email">{{email}}</h6> <img *ngIf="picture" src="{{picture}}"/> </div> </div> |
Funkcionalnost se sastoji od dohvaćanja podataka o korisniku, funkcije za odjavu koja prazni localStorage i vraća korisnika na početnu stranicu te funkcije za provjeru koja onemogućava korisnike da pristupe Dashboard stranici ako nisu prijavljeni.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
import { Component, OnInit } from '@angular/core'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Router } from '@angular/router'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.css'] }) export class DashboardComponent implements OnInit { name: string; picture: string; email: string; constructor(public _angularAuth: AngularFireAuth, private _router: Router) { } ngOnInit() { this.name = localStorage.getItem('name'); this.picture = localStorage.getItem('picture'); this.email = localStorage.getItem('email'); this.provjera(); } logout() { //this._angularAuth.auth.logout(); localStorage.clear(); console.log('logged out'); this._router.navigateByUrl('/login'); } provjera(){ if(!this.email){ this._router.navigateByUrl('/login'); } } } |
Zaključak
U ovom sam blog postu pokazao kako implementirati Google Firebase prijavu u Angular web projekt.
