View
598
Download
0
Category
Preview:
Citation preview
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
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
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
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 )
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
The client is unsafe by definitionWe can protect our data with
AuthenticationAuthorization
Validation
Programmatic AuthenticationAngularFireAuth
af.auth
.logout()this.af.auth.login({ provider: <provider>})
AuthProviders.Twitter
AuthProviders.Facebook
AuthProviders.Github
AuthProviders.Google
.getAuth().createUser()
.login()
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
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
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
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
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
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
Recommended