Share
Embed
Transcript
30 slides
-
DATA FLOW ⊗ REST API which queries database by some
parameters ⊗ Returns data in JSON format (via Observable) ⊗ Displays it on frontend ⊗ Polls every second or so to get latest data* ⊗ *or use Websockets... -
SAVING DATA INPUTTED BY USER ⊗ Handle form input ⊗
Send data to REST API ⊗ Check authorization ⊗ Save in database ⊗ Get back to the list (make sure to display new content if was created in the meantime) -
⊗ Providing REST API (which has quite repetitive methods) ⊗
… or Websockets server to ensure better experience ⊗ Maintaining database ⊗ Managing users’ sessions and authorization -
WHAT IF WE GET RID OF BACKEND? … and backend
developers? -
GOOGLE FIREBASE PLATFORM ⊗ Realtime database ⊗ Auth service ⊗
Hosting ⊗ Cloud functions ⊗ … and many more -
FIRESTORE - realtime database ⊗ Cloud hosted ⊗ NoSQL database
⊗ Client libraries for Android, iOS, Javascript (Angular, React etc.) ⊗ Oriented around documents and collections (like MongoDB) ⊗ Realtime -
FIRESTORE INSTALLATION ⊗ npm install firebase @angular/fire --save ⊗ Copy
credentials to environment.ts ⊗ Import in module: @NgModule({ imports: [ AngularFireModule.initializeApp(environment.firebase), AngularFirestoreModule, // … ], -
THE SIMPLEST COMPONENT export class AppComponent implements OnInit { meetupers$:
Observable<any[]>; constructor(private db: AngularFirestore) {} ngOnInit(): void { this.meetupers$ = this.db .collection('meetupers') .valueChanges(); } } -
EVEN SIMPLER TEMPLATE <div class="jumbotron"> <h1>Welcome to Firebase meetupers opinion
collector!</h1> </div> <h2>How would you rate Firebase's ease of use: </h2> <ul> <li *ngFor="let m of meetupers | async"> {{m.name}} {{m.score}} / 5 </li> </ul> -
SAVING DATA TEMPLATE <input placeholder="Your name" class="form-control" [formControl]="name"> <select class="form-control"
[formControl]="score"> <option *ngFor="let opt of [1, 2, 3, 4, 5]" [value]="opt">{{opt}}</option> </select> <button class="btn btn-success" (click)="save()">Save</button> -
SAVING DATA METHOD export class AppComponent implements OnInit { name
= new FormControl(''); score = new FormControl(''); save() { this.db.collection('meetupers').add({ name: this.name.value, score: parseInt(this.score.value), }).then(() => { this.name.setValue(null); this.score.setValue(null); console.log('Yass!'); }); -
LET’S TRIGGER FILTERING <h1>Welcome to Firebase meetupers opinion collector!</h1> <button
class="btn btn-warning" (click)="propagandaMode()"> Show only good reviews </button> -
HANDLING FILTERS propagandaMode() { this.meetupers$ = this.db.collection( 'meetupers', ref =>
ref.where('score', '>', 3) ).valueChanges(); } ⊗ Query options: where, orderBy, limit, startAt, startAfter, endAt, endBefore -
FIREBASE AUTH + DATABASE ⊗ Couple lines of code to
setup authentication ⊚ Federated identity providers (FB, Google, Twitter, Github) ⊚ Email and password based protection ⊚ Custom auth system integration ⊗ Wide range of possibilities of protecting collections based on auth state ⊗ FirebaseUI handles sign-in flow -
USE AngularFireAuth authState: Observable<firebase.User>; constructor(public auth: AngularFireAuth) {} ngOnInit() {
this.authState = this.auth.authState; } login() { this.auth.auth.signInWithPopup( new auth.GoogleAuthProvider() ); } -
HOW ABOUT LOGIC RELATED TO DATA? For example: send an
email when new opinion is created -
CLOUD FUNCTIONS ⊗ JS/TS function being invoked on certain trigger
⊗ Trigger can be HTTP or related to Firestore document (change, create, delete) ⊗ Ability to run any JS/TS code with any dependencies based on event data firebase deploy --only functions -
CLOUD FUNCTIONS - PREPARE import * as functions from 'firebase-functions';
import * as nodemailer from 'nodemailer'; const mailTransport = nodemailer.createTransport({ service: 'gmail', auth: { user: '***', pass: '*** }, // better: use ENV vars }); -
CLOUD FUNCTIONS - FIRESTORE ONWRITE exports.sendEmail = functions.firestore.document('/meetupers/{uid}').onWrite(async (change) =>
{ const meetuper = change.after; await mailTransport.sendMail({ from: '[email protected]', to: '[email protected]', subject: `${meetuper.get('name')}: ${meetuper.get('score')} / 5`, text: 'Yass!', }); return null; });