firebase ng2 zurich

52
Firebase and ng2 Christoffer Noring Google Developer Expert Frontend Developer OVO Energy

Upload: christoffer-noring

Post on 13-Jan-2017

600 views

Category:

Technology


0 download

TRANSCRIPT

Firebase and ng2Christoffer Noring

Google Developer ExpertFrontend Developer OVO Energy

History

Founded in 2011 by Andrew Lee and James Tamplin

Started as a realtime database + API

Is now a full suite for app development

Aquired by Google in 2014

What is Firebase - now

Backend as a service in the cloud

3-way binding

2-way bindingview model

User changesview

Model changes

View is updated Model changed byan http call for example

3-way binding

view

model

view

model

User changes view

Model changes

Triggers synchronisation

Synchronizing

Application 1 Application 2

Model changes

View is updated

Liststhere can be only object

A normal list0 : item0

1 : item1

2 : item2

User deletes

0 : item1

1 : item2Index is reassigned

The problem with a list

in realtime0 : item01 : item12 : item2User 1 deletes

User 2 deletes3 : item3

4 : item4

We would have to reassign indexes constantlyIt would be error prone

A better way

-dfgf7687: item1-123niukzu : item2-dfsd4345 : item3-324dsvsd : item4

{

}

Unique indexes

NO recalculation of index

AngularFire

Lower level API

All Firebase featuresFeatures supported by AngularFire

Angular 1AngularFire

https://github.com/angular/angularfire2

Angular 2AngularFire2

$firebaseAuthworking with authentication

$firebaseObject working with object

$firebaseArray working with lists

AngularFire

AngularFire ( 1 )

AngularFireAuthworking with authentication

FirebaseObjectObservable

working with object

FirebaseListObservable

working with lists

AngularFire

AngularFire ( 2 )

Admin tools

Setup your project

Configure authentication / authorization

And much more

What can it do for us

Firebase console

Click here

Create/import Existing projects

Your database with collectionsData tab

Add to ng2 app

Configure from code

We need this configuration

var config = { apiKey: "", authDomain: "", databaseURL: "", storageBucket: "",};@NgModule({

imports: [ AngularFireModule.initializeApp( config, { //method: AuthMethods.Popup, method: AuthMethods.Redirect } ), BrowserModule ], declarations: [ AppComponent, Theater, MovieGoer

], bootstrap: [ AppComponent ]})

app.module.ts

add to import in root module

Add configuration to module

Inject AngularFire instance, where you want to use it

class Component{ constructor(af:AngularFire){

}}

import { AngularFire } from 'angularfire2';

this.af.database.list().<operation> .object().<operation>

access data

this.af.auth.<operation> authenticate

inject

Protect our app

The client is unsafe by definitionWe can protect our data with

AuthenticationAuthorization

Validation

AuthenticationAnonymous Username/password

OAuthCustom

Plenty of available methods

Enabled methods

2 Paste

Obtain1

3Github produces client secret/id

Firebase console

Programmatic AuthenticationAngularFireAuth

af.auth

.logout()this.af.auth.login({ provider: <provider>})

AuthProviders.Twitter

AuthProviders.Facebook

AuthProviders.Github

AuthProviders.Google

.getAuth().createUser()

.login()

Authorization

Rules tab

{ "rules": { ".read": "auth == null", ".write": "auth == null" }}

{ "rules": { ".read": "auth != null", ".write": "auth != null" }}

No authorization

Authorization enabled

read accesswrite access

Set rules per collection

{ "rules": { "foo": { ".read": true, ".write": false } }}

Collection

Authorization

Understanding rule evaluation{ "rules": { "foo": { “bar” : { ".read": true, ".write": false “child” :{ } } } }}

this.af.database.object('/foo')ACCESS DENIED

Permissions are cascaded but atomic

this.af.database.object(‘/foo/bar')

ACCESS GRANTEDthis.af.database.object(‘/foo/child’)

Summary authorisation

You can set read/write rules on Whole database

Per collection

Rules are appliedAtomicallyCascading

https://firebase.google.com/docs/database/security/securing-data#predefined_variables

Validation

We can stop erroneous data from entering our databaseWe can set validation rules

{ "rules": { "order": { “name” : { }, “quantity” : { } } }}

this.order = af.database.object('/order');this.order.set({ name : “some name”})

FAILS, must have ‘quantity’

Validate structure

".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99"

{ "rules": { "order": { “name” : { }, “quantity” : {

} } }}

this.order = af.database.object('/order');this.order.set({ name : “some name”, quantity: 101})

FAILS, must be 0-99

Validate input data

Working with data

Object - Retrieve data

const relative = af.database.object('/item');Relative path

const absolute = af.database.object('https://<your-app>.firebaseio.com/item');Absolute path

@Component({ template : ` {{ ( item | async )?.name }} `})

async pipe, to unwrap value

export class AppComponent { item: FirebaseObjectObservable<any>; constructor(af: AngularFire) { this.item = af.database.object('/item'); }}

make connection

Object - Change data

const item = af.database.object('/item');

Destructive{ item : { abc : “123” }}

item.set({ prop : val })

Non Destructive{ item : { abc : “123” }}

item.update({ prop : val })

Data replaced{ item : { prop : val }}

Data amended{ item : { abc : “123”, prop : val }}

List - Retrieve data

Relative pathconst relative = af.database.list('/items');

Absolute pathconst absolute = af.database.list('https://<your-app>.firebaseio.com/items');

Queryconst queryList = af.database.list('/items', { query: { limitToLast: 10, orderByKey: true }});

List - Change data

const items = af.database.list('/items');

items.push( object ) Addupdate(keyRefOrSnap: string) Update item in listitems.remove( key:string ) Remove item in listitems.remove( ) Remove entire list

<li *ngFor="let item of items | async"> <input type="text" #updatetext [value]="item.text" /> <button (click)="updateItem(item.$key, updatetext.value)”>Update</button></li>

$key, $value

Respond to change

Every reference is an observable This is usually enough

Every action returns a promise For capturing auth errors and debug

const item = af.database.object('/item');item.subscribe( (data) => { console.log(‘something happened’) } )

Indicate change with css

var promise = item.set({ prop : newValue })promise.then( (data) = > { console.log(‘success’); }, (err) => { console.log(‘action failed for some reason’) } )

Indicate operation result

Data design best practices

Avoid nesting of data

{ foo : { bar : { something : { …… } } }}

32 levels are allowed, but don’t do it

You will get all child data, might be massive

Hard to keep track of access

Instead - shallow trees

{ orders : { orderid1 : { title : ‘some title’, timestamp : ‘fsdfsdfs’ }, orderid2 : { title : ‘some title’, timestamp : ‘fsdfsdfs’ } }}

Meta data { orderitems : { orderid1 : { orderitem_id_1 : { title : ‘tomato’, price : 5 }, orderitem_id_2 : { title : ‘cucumber’, price : 25 } }, orderid2 : { orderitem_id_3 : { title : ‘tomato’, price : 5 } } }}

Detailed data

Summary

AngularFire is a wrapper around Firebase APIAngularFire is for Angular1AngularFire2 is for Angular2

Simple API, list, object, auth

References are ObservablesActions are Promises

Firebase is backend as a service

Your data is protected by authentication, authorisation and validation

It is a platform - not just the database, use all of it

Thank you