Você está na página 1de 22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

AngularFire

View onGitHub

Issues

ANGULARFIRE
AngularFireistheofficiallysupportedAngularJSbindingforFirebase.Thisbindingletsyouassociate Firebase
referenceswithAngularmodelssothattheywillbetransparentlyandimmediatelykeptinsyncwiththedatabase
andwithallotherclientscurrentlyusingyourapplication.
ThefocusofthislibraryistoabstractmuchoftheboilerplateinvolvedincreatingAngularbindingsfromFirebase
toAngular,andtomakeiteasytocreateservicesthatsynctoyourdatabase.However,thislibrarydoesnot
attempttoreplacethecapabilitiesoftheentireFirebaseclientlibrarysAPIandthatmaystillbesuitableforsome
advancedusages.FeelfreetousethemethodsprovidedbythecoreFirebaseclientlibraryalongsidethe
AngularFirebinding.

$FIREBASEOBJECT
The $firebaseObject servicetakesa Firebase referenceorFirebase Query andreturnsaJavaScriptobject
whichcontainsthedataattheprovided Firebase referenceandsomeextraAngularFirespecificfields.Notethat
thedatawillnotbeavailableimmediatelysinceretrievingitisanasynchronousoperation.Youcanusethe
$loaded() promisetogetnotifiedwhenthedatahasloaded.

ThisserviceautomaticallykeepslocalobjectsinsyncwithanychangesmadetotheremoteFirebasedatabase.
However,notethatanychangestothatobjectwillnotautomaticallyresultinanychangestothe
remotedata.Allsuchchangeswillhavetobeperformedbyupdatingtheobjectdirectlyandthencalling
$save() ontheobject,orbyutilizing $bindTo() (seemorebelow).

app.controller("MyCtrl",["$scope","$firebaseObject",
function($scope,$firebaseObject){
varref=newFirebase(URL)

varobj=$firebaseObject(ref)

//totakeanactionafterthedataloads,usethe$loaded()promise
obj.$loaded().then(function(){
console.log("loadedrecord:",obj.$id,obj.someOtherKeyInData)

//Toiteratethekey/valuepairsoftheobject,useangular.forEach()
angular.forEach(obj,function(value,key){
console.log(key,value)
})
})

//TomakethedataavailableintheDOM,assignitto$scope
$scope.data=obj

//Forthreewaydatabindings,bindittothescopeinstead
obj.$bindTo($scope,"data")
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

1/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

}
])

$id

Thekeywherethisrecordisstored.Thesameas obj.$ref().key() .

$priority

Thepriorityforthisrecordaccordingtothelastupdatewereceived.Modifyingthisvalueandthencalling
$save() willalsoupdatetheserverspriority.

IMPORTANTNOTE:BecauseAngulars $watch() functionignoreskeysprefixedwith $ ,changingthisfield


insidethe $bindTo() functionwillnottriggeranupdateunlessafieldwithouta $ prefixisalsoupdated.Itis
besttoavoidusing $bindTo() forediting $ variablesandjustrelyonthe $save() method.

$value

Ifthevalueinthedatabaseisaprimitive(boolean,string,ornumber)thenthevaluewillbestoredunderthis
$value key.Modifyingthisvalueandthencalling $save() willalsoupdatetheserversvalue.

Notethatanytimeotherkeysexist,thisonewillbeignored.Tochangeanobjecttoaprimitivevalue,deletethe
otherkeysandaddthiskeytotheobject.Asashortcut,wecanuse:

varobj=$firebaseObject(ref)//anobjectwithdatakeys
$firebaseUtils.updateRec(obj,newPrimitiveValue)//updateRecwilldeletetheotherkeysforus

IMPORTANTNOTE:BecauseAngulars $watch() functionignoreskeysprefixedwith $ ,changingthisfield


insidethe $bindTo() functionwillnottriggeranupdateunlessafieldwithouta $ prefixisalsoupdated.Itis
besttoavoidusing $bindTo() forediting $ variablesandjustrelyonthe $save() method.

$remove()

Removestheentireobjectlocallyandfromthedatabase.Thismethodreturnsapromisethatwillbefulfilledwhen
thedatahasbeenremovedfromtheserver.Thepromisewillberesolvedwitha Firebase referenceforthe
exterminatedrecord.

varobj=$firebaseObject(ref)
obj.$remove().then(function(ref){
//datahasbeendeletedlocallyandinthedatabase
},function(error){
console.log("Error:",error)
})

$save()
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

2/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Ifchangesaremadetodata,thencalling $save() willpushthosechangestotheserver.Thismethodreturnsa


promisethatwillresolvewiththisobjects Firebase referencewhenthewriteiscompleted.

varobj=$firebaseObject(ref)
obj.foo="bar"
obj.$save().then(function(ref){
ref.key()===obj.$id//true
},function(error){
console.log("Error:",error)
})

$loaded()

Returnsapromisewhichisresolvedwhentheinitialobjectdatahasbeendownloadedfromthedatabase.The
promiseresolvestothe $firebaseObject itself.

varobj=$firebaseObject(ref)
obj.$loaded()
.then(function(data){
console.log(data===obj)//true
})
.catch(function(error){
console.error("Error:",error)
})

Asashortcut,the resolve() / reject() methodscanoptionallybepasseddirectlyinto $loaded() :

varobj=$firebaseObject(ref)
obj.$loaded(
function(data){
console.log(data===obj)//true
},
function(error){
console.error("Error:",error)
}
)

$ref()

Returnsthe Firebase referenceusedtocreatethisobject.

varob=$firebaseObject(ref)
obj.$ref()===ref//true

$bindTo(scope,varName)
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

3/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Createsathreewaybindingbetweenascopevariableandthedatabasedata.Whenthe scope dataisupdated,


changesarepushedtothedatabase,andwhenchangesoccurinthedatabase,theyarepushedinstantlyinto
scope .Thismethodreturnsapromisethatresolvesaftertheinitialvalueispulledfromthedatabaseandsetin

the scope variable.

varref=newFirebase(URL)//assumevaluehereis{foo:"bar"}
varobj=$firebaseObject(ref)

obj.$bindTo($scope,"data").then(function(){
console.log($scope.data)//{foo:"bar"}
$scope.data.foo="baz"//willbesavedtothedatabase
ref.set({foo:"baz"})//thiswouldupdatethedatabaseand$scope.data
})

WecannowbindtoanypropertyonourobjectdirectlyintheHTML,andhaveitsavedinstantlytothedatabase.
SecurityandFirebaseRulescanbeusedforvalidationtoensuredataisformattedcorrectlyattheserver.

<!
Thisinputfieldhasthreewaydatabindingtothedatabase
(changingvalueupdatesremotedataremotechangesareappliedhere)
>
<inputtype="text"ngmodel="data.foo"/>

Onlyonescopevariablecanbeboundatatime.Ifasecondattemptstobindtothesame $firebaseObject
instance,thepromisewillberejectedandthebindwillfail.
IMPORTANTNOTE:Angulardoesnotreportvariablesprefixedwith $ toany $watch() listeners.asimple
workaroundhereistouseavariableprefixedwith _ ,whichwillnotbesavedtotheserver,butwilltrigger
$watch() .

varobj=$firebaseObject(ref)
obj.$bindTo($scope,"widget").then(function(){
$scope.widget.$priority=99
$scope.widget._updated=true
})

If $destroy() isemittedby scope (thishappenswhenacontrollerisdestroyed),thenthisobjectis


automaticallyunboundfrom scope .Itcanalsobemanuallyunboundusingthe unbind() method,whichis
passedintothepromisecallback.

varobj=$firebaseObject(ref)
obj.$bindTo($scope,"data").then(function(unbind){
//unbindthislater
//unbind()
})

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

4/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$watch(callback,context)

Registersaneventlistenerwhichwillbenotifiedanytimethereisachangetothedata.Returnsanunregister
functionthat,wheninvoked,willstopnotifyingthecallbackofchanges.

varobj=$firebaseObject(ref)
varunwatch=obj.$watch(function(){
console.log("datachanged!")
})

//atsometimeinthefuture,wecanunregisterusing
unwatch()

$destroy()

Callingthismethodcancelseventlistenersandfreesmemoryusedbythisobject(deletesthelocaldata).
Changesarenolongersynchronizedtoorfromthedatabase.

$FIREBASEARRAY
The $firebaseArray servicetakesa Firebase referenceorFirebase Query andreturnsaJavaScriptarray
whichcontainsthedataattheprovided Firebase reference.Notethatthedatawillnotbeavailableimmediately
sinceretrievingitisanasynchronousoperation.Youcanusethe $loaded() promisetogetnotifiedwhenthe
datahasloaded.
Thisserviceautomaticallykeepsthislocalarrayinsyncwithanychangesmadetotheremotedatabase.Thisis
aPSEUDOREADONLYARRAYsuitableforuseindirectiveslike ngrepeat andwithAngularfilters(which
expectanarray).
Whileusingreadattributesandmethodslike length and toString() willworkgreatonthisarray,youshould
avoiddirectlymanipulatingthearray.Methodslike splice() , push() , pop() , shift() , unshift() ,and
reverse() willcausethelocaldatatobecomeoutofsyncwiththeserver.Instead,utilizethe $add() ,
$remove() ,and $save() methodsprovidedbytheservicetochangethestructureofthearray.Togettheidof

anitemina$firebaseArraywithin ngrepeat ,call $id onthatitem.

//JavaScript
app.controller("MyCtrl",["$scope","$firebaseArray",
function($scope,$firebaseArray){
varlist=$firebaseArray(newFirebase(URL))

//addanitem
list.$add({foo:"bar"}).then(...)

//removeanitem
list.$remove(2).then(...)

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

5/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

//makethelistavailableintheDOM
$scope.list=list
}
])

<!HTML>
<lingrepeat="iteminlist|filter:name">{{item|json}}</li>

The $firebaseArray servicecanalsotakeaquerytoonlysyncasubsetofdata.

app.controller("MyCtrl",["$scope","$firebaseArray",
function($scope,$firebaseArray){
varmessagesRef=newFirebase(URL).child("messages")
varquery=messagesRef.orderByChild("timestamp").limitToLast(10)

varlist=$firebaseArray(query)
}
])

Notethat,whilethearrayitselfshouldnotbemodified,itispracticaltochangespecificelementsofthearrayand
savethembacktotheremotedatabase:

//JavaScript
varlist=$firebaseArray(newFirebase(URL))
list[2].foo="bar"
list.$save(2)

<!HTML>
<lingrepeat="iteminlist">
<inputngmodel="item.foo"ngchange="list.$save(item)"/>
</li>

$add(newData)

Createsanewrecordinthedatabaseandaddstherecordtoourlocalsynchronizedarray.
Thismethodreturnsapromisewhichisresolvedafterdatahasbeensavedtotheserver.Thepromiseresolvesto
the Firebase referenceforthenewlyaddedrecord,providingeasyaccesstoitskey.

varlist=$firebaseArray(ref)
list.$add({foo:"bar"}).then(function(ref){
varid=ref.key()
console.log("addedrecordwithid"+id)
list.$indexFor(id)//returnslocationinthearray
})

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

6/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$remove(recordOrIndex)

Removearecordfromthedatabaseandfromthelocalarray.Thismethodreturnsapromisethatresolvesafter
therecordisdeletedattheserver.Itwillcontaina Firebase referencetothedeletedrecord.Itacceptseitheran
arrayindexorareferencetoanitemthatexistsinthearray.

varlist=$firebaseArray(ref)
varitem=list[2]
list.$remove(item).then(function(ref){
ref.key()===item.$id//true
})

$save(recordOrIndex)

Thearrayitselfcannotbemodified,butrecordsinthearraycanbeupdatedandsavedbacktothedatabase
individually.Thismethodsavesanexisting,modifiedlocalrecordbacktothedatabase.Itacceptseitheranarray
indexorareferencetoanitemthatexistsinthearray.

$scope.list=$firebaseArray(ref)

<lingrepeat="iteminlist">
<inputtype="text"ngmodel="item.title"ngchange="list.$save(item)"/>
</li>

Thismethodreturnsapromisewhichisresolvedafterdatahasbeensavedtotheserver.Thepromiseresolvesto
the Firebase referenceforthesavedrecord,providingeasyaccesstoitskey.

varlist=$firebaseArray(ref)
list[2].foo="bar"
list.$save(2).then(function(ref){
ref.key()===list[2].$id//true
})

$getRecord(key)

Returnstherecordfromthearrayforthegivenkey.Ifthekeyisnotfound,returns null .Thismethodutilizes


$indexFor(key) tofindtheappropriaterecord.

varlist=$firebaseArray(ref)
varrec=list.$getRecord("foo")//recordwith$id==="foo"ornull

$keyAt(recordOrIndex)

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

7/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Returnsthekeyforarecordinthearray.Itacceptseitheranarrayindexorareferencetoanitemthatexistsin
thearray.

//assumerecords"alpha","bravo",and"charlie"
varlist=$firebaseArray(ref)
list.$keyAt(1)//bravo
list.$keyAt(list[1])//bravo

$indexFor(key)

Theinverseof $keyAt() ,thismethodtakesakeyandfindstheassociatedrecordinthearray.Iftherecorddoes


notexist,1isreturned.

//assumerecords"alpha","bravo",and"charlie"
varlist=$firebaseArray(ref)
list.$indexFor("alpha")//0
list.$indexFor("bravo")//1
list.$indexFor("zulu")//1

$loaded()

Returnsapromisewhichisresolvedwhentheinitialarraydatahasbeendownloadedfromthedatabase.The
promiseresolvestothe $firebaseArray .

varlist=$firebaseArray(ref)
list.$loaded()
.then(function(x){
x===list//true
})
.catch(function(error){
console.log("Error:",error)
})

Theresolve/rejectmethodsmayalsobepasseddirectlyinto$loaded:

varlist=$firebaseArray(ref)
list.$loaded(
function(x){
x===list//true
},function(error){
console.error("Error:",error)
})

$ref()

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

8/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Returnsthe Firebase referenceusedtocreatethisarray.

varlist=$firebaseArray(ref)
sync===list.$ref()//true

$watch(cb[,context])

Anycallbackpassedherewillbeinvokedeachtimedatainthearrayisupdatedfromtheserver.Thecallback
receivesanobjectwiththefollowingkeys:
event :Thedatabaseeventtypewhichfired( child_added , child_moved , child_removed ,or
child_changed ).
key :TheIDoftherecordthattriggeredtheevent.
prevChild :Ifeventis child_added or child_moved ,thiscontainsthepreviousrecordskeyor null if
key belongstothefirstrecordinthecollection.

varlist=$firebaseArray(ref)

list.$watch(function(event){
console.log(event)
})

//logs{event:"child_removed",key:"foo"}
list.$remove("foo")

//logs{event:"child_added",key:"<new_id>",prevId:"<prev_id>"}
list.$add({hello:"world"})

Acommonusecaseforthiswouldbetocustomizethesortingforasynchronizedarray.Sinceeachtimeanadd
orupdatearrivesfromtheserver,thedatacouldbecomeoutoforder,wecanresortoneachevent.Wedont
havetoworryaboutexcessiveresortsslowingdownAngularscompileprocess,orcreatingexcessiveDOM
updates,becausetheeventsarealreadybatchednicelyintoasingle $apply event(wegatherthemupand
triggertheeventsinbatchesbeforetelling $digest todirtycheck).

varlist=$firebaseArray(ref)

//sortourlist
list.sort(compare)

//eachtimetheserversendsrecords,resort
list.$watch(function(){list.sort(compare)})

//customsortingroutine(sortbylastname)
functioncompare(a,b){
returna.lastName.localeCompare(b.lastName)
}

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

9/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$destroy()

Stoplisteningforeventsandfreememoryusedbythisarray(emptiesthelocalcopy).Changesarenolonger
synchronizedtoorfromthedatabase.

EXTENDINGTHESERVICES
Thereareseveralpowerfultechniquesfortransformingthedatadownloadedandsavedby $firebaseArray and
$firebaseObject .ThesetechniquesshouldonlybeattemptedbyadvancedAngularuserswhoknow

theirwayaroundthecode.

$firebaseObject.$extend

Youcancreateanewfactoryfroma $firebaseObject .Itcanaddadditionalmethodsoroverrideanyexisting


method.

varColorFactory=$firebaseObject.$extend({
getMyFavoriteColor:function(){
returnthis.favoriteColor+",nogreen!"//obscureMontyPythonreference
}
})

varfactory=newColorFactory(ref)
varfavColor=factory.getMyFavoriteColor()

Thistechniquecanalsobeusedtotransformhowdataisstoredandsavedbyoverridingthefollowingprivate
methods:
$$updated:Calledwithasnapshotanytimea value eventisreceivedfromthedatabase,mustapplythe
updatesandreturntrueifanychangesoccurred.
$$error:Passedan Error anytimeasecurityerroroccurs.Thesearegenerallynotrecoverable.
$$notify:Sendsnotificationstoanylistenersregisteredwith $watch() .
toJSON:Aswithanyobject,ifa toJSON() methodisprovided,itwillbeusedby JSON.stringify() to
parsetheJSONcontentbeforeitissavedtothedatabase.
$$defaults:Akey/valuepairthatcanbeusedtocreatedefaultvaluesforanyfieldswhicharenotfoundin
theserverdata(i.e.undefinedfields).Bydefault,theyareappliedeachtime $$updated isinvoked.Ifthat
methodisoverridden,itwouldneedtoimplementthisbehavior.

//Addacountertoourobject...
varFactoryWithCounter=$firebaseObject.$extend({
//addamethodtotheprototypethatreturnsourcounter
getUpdateCount:function(){returnthis._counter},

//eachtimeanupdatearrivesfromtheserver,applythechangelocally
$$updated:function(snap){
//applythechangesusingthesupermethod
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

10/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

varchanged=$firebaseObject.prototype.$$updated.apply(this,arguments)

//add/incrementacountereachtimethereisanupdate
if(!this._counter){this._counter=0}
this._counter++

//returnwhetherornotchangesoccurred
returnchanged
}
})

$firebaseArray.$extend

Youcancreateanewfactoryfroma $firebaseArray .Itcanaddadditionalmethodsoroverrideanyexisting


method.

app.factory("ArrayWithSum",function($firebaseArray){
return$firebaseArray.$extend({
sum:function(){
vartotal=0
angular.forEach(this.$list,function(rec){
total+=rec.x
})
returntotal
}
})
})

Wecanthenusethisfactorywithbyinstantiatingit:

varlist=newArrayWithSum(ref)
list.$loaded().then(function(){
console.log("Listhas"+list.sum()+"items")
})

Thistechniquecanbeusedtotransformhowdataisstoredbyoverridingthefollowingprivatemethods:
$$added:CalledwithasnapshotandprevChildanytimea child_added eventoccurs.
$$updated:Calledwithasnapshotanytimea child_changed eventoccurs.
$$moved:CalledwithasnapshotandprevChildanytime child_moved eventoccurs.
$$removed:Calledwithasnapshotanytimea child_removed eventoccurs.
$$error:Passedan Error anytimeasecurityerroroccurs.Thesearegenerallynotrecoverable.
$$getKey:TellsAngularFirewhattheuniqueIDisforeachrecord(thedefaultjustreturns this.$id ).
$$notify:Notifiesanylistenersregisteredwith$watchnormallythismethodwouldnotbemodified.
$$process:Handlestheactualsplicingofdataintoandoutofthearray.Normallythismethodwouldnotbe
modified.
$$defaults:Akey/valuepairthatcanbeusedtocreatedefaultvaluesforanyfieldswhicharenotfoundin
theserverdata(i.e.undefinedfields).Bydefault,theyareappliedeachtime $$added or $$updated are
invoked.Ifthosemethodsareoverridden,theywouldneedtoimplementthisbehavior.
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

11/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Toillustrate,letscreateafactorythatcreates Widget instances,andtransformsdates:

//anobjecttoreturninourWidgetFactory
app.factory("Widget",function($firebaseUtils){
functionWidget(snapshot){
//storetherecordidsoAngularFirecanidentifyit
this.$id=snapshot.key()

//applythedata
this.update(snapshot)
}

Widget.prototype={
update:function(snapshot){
varoldData=angular.extend({},this.data)

//applychangestothis.datainsteadofdirectlyon`this`
this.data=snapshot.val()

//addaparseddatetoourwidget
this._date=newDate(this.data.date)

//determineifanythingchanged,notethatangular.equalswillnotcheck
//$valueor$priority(sinceitexcludesanythingthatstartswith$)
//sobecarefulwhenusingangular.equals()
return!angular.equals(this.data,oldData)
},

getDate:function(){
returnthis._date
},

toJSON:function(){
//sincewechangedwhereourdataisstored,weneedtotellAngularFirehow
//togettheJSONversionofit.Wecanuse$firebaseUtils.toJSON()toremove
//privatevariables,copythedataintoashippableformat,anddovalidation
return$firebaseUtils.toJSON(this.data)
}
}

returnWidget
})

//nowlet'screateasynchronizedarrayfactorythatusesourWidget
app.factory("WidgetFactory",function($firebaseArray,Widget){
return$firebaseArray.$extend({
//changetheaddedbehaviortoreturnWidgetobjects
$$added:function(snap){
//insteadofcreatingthedefaultPOJO(plainoldJavaScriptobject)
//wewillreturnaninstanceoftheWidgetclasseachtimeachild_added
//eventisreceivedfromtheserver
returnnewWidget(snap)
},

//overridetheupdatebehaviortocallWidget.update()
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

12/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$$updated:function(snap){
//weneedtoreturntrue/falsehereor$watchlistenerswillnotgettriggered
//luckily,ourWidget.prototype.update()methodalreadyreturnsabooleanif
//anythinghaschanged
returnthis.$getRecord(snap.key()).update(snap)
}
})
})

PassingaClassinto$extend

Insteadofjustalistoffunctions,wecanalsopassinaclassconstructortoinheritmethodsfrom
$firebaseArray .Theprototypeforthisclasswillbepreserved,anditwillinheritfrom $firebaseArray .

Thisisanextremelyadvancedfeature.Donotusethisunlessyouknowthatyouneedit
Thisclassconstructorisexpectedtocall $firebaseArray sconstructor(i.e.thesuperconstructor).
Thefollowingfactoryaddsanupdatecounterwhichisincrementedeachtime $$added() or $$updated() is
called:

app.factory("ArrayWithCounter",function($firebaseArray,Widget){
//$firebaseArrayand$firebaseObjectconstructorsbothacceptasingleargument,a`Firebase`ref
functionArrayWithCounter(ref){
//initializeacounter
this.counter=0

//callthesuperconstructor
return$firebaseArray.call(this,ref)
}

//overridetheaddbehaviortoreturnaWidget
ArrayWithCounter.prototype.$$added=function(snap){
returnnewWidget(snap)
}

//overridetheupdatebehaviortocallWidget.update()
ArrayWithCounter.prototype.$$updated=function(snap){
varwidget=this.$getRecord(snap.key())
returnwidget.update()
}

//passourconstructorto$extend,whichwillautomaticallyextractthe
//prototypemethodsandcalltheconstructorappropriately
return$firebaseArray.$extend(ArrayWithCounter)
})

DecoratingtheS ervices

Ingeneral,itwillbemoreusefultoextendtheservicestocreatenewservicesthantousethistechnique.
However,itisalsopossibletomodify $firebaseArray or $firebaseObject globallybyusingAngulars
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

13/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$decorate() method.

app.config(function($provide){
$provide.decorator("$firebaseObject",function($delegate,$firebaseUtils){
var_super=$delegate.prototype.$$updated

//overrideanyinstanceof$firebaseObjecttolookforadatefield
//andtransformsittoaDateobject.
$delegate.prototype.$$updated=function(snap){
varchanged=_super.call(this,snap)
if(this.hasOwnProperty("date")){
this._dateObj=newDate(this.date)
}
returnchanged
}

//addamethodthatfetchesthedateobjectwejustcreated
$delegate.prototype.getDate=function(){
returnthis._dateObj
}

//variablesstartingwith_areignoredbyAngularFiresowedon'tneed
//toworryaboutthetoJSONmethodhere

return$delegate
})
})

CREATINGANGULARFIRESERVICES
WiththeabilitytoextendtheAngularFireservices,servicescanbebuilttorepresentoursynchronizedcollections
withaminimalamountofcode.Forexample,wecancreatea User factory:

//createaUserfactorywithagetFullName()method
app.factory("UserFactory",function($firebaseObject){
return$firebaseObject.$extend({
getFullName:function(){
//concatenatefirstandlastname
returnthis.first_name+""+this.last_name
}
})
})

Andcreateanewinstance:

//createaUserobjectfromourFactory
app.factory("User",function(UserFactory){
varref=newFirebase(URL+"/users/")
returnfunction(userid){
returnnewUserFactory(ref.child(userid))
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

14/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

}
})

Similarly,wecanextend $firebaseArray bycreatinga Message object:

app.factory("Message",function($firebaseArray){
functionMessage(snap){
//storetheuserIDsoAngularFirecanidentifytherecords
//inthiscase,westoreitinacustomlocation,sowe'llneed
//tooverride$$getKey
this.message_id=snap.key()
this.message=snap.val()
}
Message.prototype={
update:function(snap){
//storeastringintothis.message(insteadofthedefault$value)
if(snap.val()!==this.message){
this.message=snap.val()
returntrue
}
returnfalse
},
toJSON:function(){
//tellAngularFirewhatdatatosave,inthiscaseastring
returnthis.message
}
}

returnMessage
})

Wecanthenusethattoextendthe $firebaseArray factory:

app.factory("MessageFactory",function($firebaseArray,Message){
return$firebaseArray.$extend({
//overridethe$createObjectbehaviortoreturnaMessageobject
$$added:function(snap){
returnnewMessage(snap)
},

//overridethe$$updatedbehaviortocallamethodontheMessage
$$updated:function(snap){
varmsg=this.$getRecord(snap.key())
returnmsg.update(snap)
},

//ourmessagesstoretheuniqueidinaspeciallocation,sotell$firebaseArray
//howtofindtheidforeachrecord
$$getKey:function(rec){
returnrec.message_id
}
})
})
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

15/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Andfinally,wecanputitalltogetherintoasynchronizedlistofmessages:

app.factory("MessageList",function(MessageFactory){
returnfunction(ref){
returnnewMessageFactory(ref)
}
})

USERSANDAUTHENTICATION
AngularFireincludessupportforuserauthenticationandmanagementwiththe $firebaseAuth service.

varapp=angular.module("app",["firebase"])

Note:The $firebaseAuth servicerequiresFirebase1.1.0orlater.

AuthenticationS erviceConstructor

The $firebaseAuth factorytakesa Firebase referenceasitsonlyargument.Notethattheauthentication


stateisglobaltoyourapplication,evenifmultiple $firebaseAuth objectsarecreated.

app.controller("MyAuthCtrl",["$scope","$firebaseAuth",
function($scope,$firebaseAuth){
varref=newFirebase("https://<YOURFIREBASEAPP>.firebaseio.com")
$scope.authObj=$firebaseAuth(ref)
}
])

Theauthenticationobjectreturnedby $firebaseAuth containsseveralmethodsforauthenticatingusers,


respondingtochangesinauthenticationstate,andmanaginguseraccountsforemail/passwordusers.

$authWithCustomToken(authToken[,options])

Authenticatestheclientusingacustomauthenticationtoken.Thisfunctiontakestwoarguments:an
authenticationtokenoraFirebaseSecretandanobjectcontainingoptionalclientarguments,suchasconfiguring
sessionpersistence.

$scope.authObj.$authWithCustomToken("<CUSTOM_AUTH_TOKEN>").then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

16/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

Thismethodreturnsapromisewhichisresolvedorrejectedwhentheauthenticationattemptiscompleted.If
successful,thepromisewillbefulfilledwithanobjectcontainingthepayloadoftheauthenticationtoken.If
unsuccessful,thepromisewillberejectedwithan Error object.
ReadourdocumentationonCustomLoginformoredetailsaboutgeneratingyourowncustomauthentication
tokens.

$authAnonymously([options])

Authenticatestheclientusinganew,temporaryguestaccount.Thisfunctiontakesoneargument:anobject
containingoptionalclientarguments,suchasconfiguringsessionpersistence.

$scope.authObj.$authAnonymously().then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

Thismethodreturnsapromisewhichisresolvedorrejectedwhentheauthenticationattemptiscompleted.If
successful,thepromisewillbefulfilledwithanobjectcontainingauthenticationdataabouttheloggedinuser.If
unsuccessful,thepromisewillberejectedwithan Error object.
Readourdocumentationonanonymousauthenticationformoredetailsaboutanonymousauthentication.

$authWithPassword(credentials[,options])

Authenticatestheclientusinganemail/passwordcombination.Thisfunctiontakestwoarguments:anobject
containing email and password attributescorrespondingtotheuseraccountandanobjectcontainingoptional
clientarguments,suchasconfiguringsessionpersistence.

$scope.authObj.$authWithPassword({
email:"my@email.com",
password:"mypassword"
}).then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

Thismethodreturnsapromisewhichisresolvedorrejectedwhentheauthenticationattemptiscompleted.If
successful,thepromisewillbefulfilledwithanobjectcontainingauthenticationdataabouttheloggedinuser.If
unsuccessful,thepromisewillberejectedwithan Error object.
Readourdocumentationonemail/passwordauthenticationformoredetailsaboutemail/password
authentication.

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

17/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$authWithOAuthPopup(provider[,options])

AuthenticatestheclientusingapopupbasedOAuthflow.Thisfunctiontakestwoarguments:theuniquestring
identifyingtheOAuthprovidertoauthenticatewith(e.g. "google" )andanobjectcontainingoptionalclient
arguments,suchasconfiguringsessionpersistence.

$scope.authObj.$authWithOAuthPopup("google").then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

Thismethodreturnsapromisewhichisresolvedorrejectedwhentheauthenticationattemptiscompleted.If
successful,thepromisewillbefulfilledwithanobjectcontainingauthenticationdataabouttheloggedinuser.If
unsuccessful,thepromisewillberejectedwithan Error object.
FirebasecurrentlysupportsFacebook,GitHub,Google,andTwitterauthentication.Refertothetableonouruser
authenticationdocumentationforinformationaboutconfiguringeachprovider.

$authWithOAuthRedirect(provider[,options])

AuthenticatestheclientusingaredirectbasedOAuthflow.Thisfunctiontakestwoarguments:theuniquestring
identifyingtheOAuthprovidertoauthenticatewith(e.g. "google" )andanobjectcontainingoptionalclient
arguments,suchasconfiguringsessionpersistence.

$scope.authObj.$authWithOAuthRedirect("google").then(function(authData){
console.log("Loggedinas:",authData.uid)
}).then(function(){
//Nevercalledbecauseofpageredirect
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

Thismethodreturnsarejectedpromisewithan Error objectiftheauthenticationattemptfails.Uponsuccessful


authentication,thebrowserwillberedirectedaspartoftheOAuthauthenticationflow.Assuch,thereturned
promisewillneverbefulfilled.Instead,youshouldusethe $onAuth() methodtodetectwhentheauthentication
hasbeensuccessfullycompleted.
FirebasecurrentlysupportsFacebook,GitHub,Google,andTwitterauthentication.Refertothetableonouruser
authenticationdocumentationforinformationaboutconfiguringeachprovider.

$authWithOAuthToken(provider,credentials[,options])

AuthenticatestheclientusingOAuthaccesstokensorcredentials.Thisfunctiontakesthreearguments:the
uniquestringidentifyingtheOAuthprovidertoauthenticatewith(e.g. "google" ),eitherastring,suchasan
OAuth2.0accesstoken,oranobjectofkey/valuepairs,suchasasetofOAuth1.0acredentials,andanobject
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

18/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

containingoptionalclientarguments,suchasconfiguringsessionpersistence.

$scope.authObj.$authWithOAuthToken("google","<ACCESS_TOKEN>").then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Authenticationfailed:",error)
})

Thismethodreturnsapromisewhichisresolvedorrejectedwhentheauthenticationattemptiscompleted.If
successful,thepromisewillbefulfilledwithanobjectcontainingauthenticationdataabouttheloggedinuser.If
unsuccessful,thepromisewillberejectedwithan Error object.
FirebasecurrentlysupportsFacebook,GitHub,Google,andTwitterauthentication.Refertothetableonouruser
authenticationdocumentationforinformationaboutconfiguringeachprovider.

$getAuth()

Synchronouslyretrievesthecurrentauthenticationstateoftheclient.Iftheuserisauthenticated,anobject
containingthefields uid (theuniqueuserID), provider (stringidentifyingtheprovider), auth (the
authenticationtokenpayload),and expires (expirationtimeinsecondssincetheUnixepoch)andmore,
dependingupontheproviderusedtoauthenticatewillbereturned.Otherwise,thereturnvaluewillbe null .

varauthData=$scope.authObj.$getAuth()

if(authData){
console.log("Loggedinas:",authData.uid)
}else{
console.log("Loggedout")
}

$onAuth(callback[,context])

Listensforchangestotheclientsauthenticationstate.Theprovided callback willfirewhentheclients


authenticatestatechanges.Ifauthenticated,thecallbackwillbepassedanobjectcontainingthefields uid (the
uniqueuserID), provider (stringidentifyingtheprovider), auth (theauthenticationtokenpayload),and
expires (expirationtimeinsecondssincetheUnixepoch)andmore,dependingupontheproviderusedto

authenticate.Otherwise,thecallbackwillbepassed null .

$scope.authObj.$onAuth(function(authData){
if(authData){
console.log("Loggedinas:",authData.uid)
}else{
console.log("Loggedout")
}
})

Thismethodcanalsotakeanoptionalsecondargumentwhich,ifprovided,willbeusedas this whencalling


https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

19/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

yourcallback.
Thismethodreturnsafunctionwhichcanbeusedtounregistertheprovided callback .Oncethe callback is
unregistered,changesinauthenticationstatewillnotcausethe callback tofire.

varoffAuth=$scope.authObj.$onAuth(callback)

//...sometimelater,unregisterthecallback
offAuth()

$unauth()

UnauthenticatesaclientfromtheFirebasedatabase.Ittakesnoargumentsandreturnsnovalue.Whenlogoutis
called,the $onAuth() callback(s)willbefired.

<spanngshow="authData">
{{authData.name}}|<ahref="#"ngclick="authObj.$unauth()">Logout</a>
</span>

$waitForAuth()

Helpermethodwhichreturnsapromisefulfilledwiththecurrentauthenticationstate.Thisisintendedtobeused
inthe resolve() methodofAngularrouters.SeetheUsingAuthenticationwithRouterssectionofour
AngularFireguideformoreinformationandafullexample.

$requireAuth()

Helpermethodwhichreturnsapromisefulfilledwiththecurrentauthenticationstateiftheuserisauthenticated
butotherwiserejectsthepromise.Thisisintendedtobeusedinthe resolve() methodofAngularroutersto
preventedunauthenticatedusersfromseeingauthenticatedpagesmomentarilyduringpageload.SeetheUsing
AuthenticationwithRouterssectionofourAngularFireguideformoreinformationandafullexample.

$createUser(credentials)

Createsanewuseraccountusinganemail/passwordcombination.Thisfunctionreturnsapromisethatis
resolvedwithanobjectcontaininguserdataaboutthecreateduser.Currently,theobjectonlycontainsthe
createdusers uid .

$scope.authObj.$createUser({
email:"my@email.com",
password:"mypassword"
}).then(function(userData){
console.log("User"+userData.uid+"createdsuccessfully!")

return$scope.authObj.$authWithPassword({
email:"my@email.com",
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

20/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

password:"mypassword"
})
}).then(function(authData){
console.log("Loggedinas:",authData.uid)
}).catch(function(error){
console.error("Error:",error)
})

Notethatthisfunctiononlycreatestheuser.Ifyouwishtologinasthenewlycreateduser,call
$authWithPassword() afterthepromiseforthismethodhasbeenfulfilled.

$changePassword(credentials)

Changesthepasswordofanexistinguserusinganemail/passwordcombination.Thisfunctionreturnsa
promisethatisresolvedwhenthepasswordhasbeensuccessfullychangedontheFirebaseauthentication
servers.

$scope.authObj.$changePassword({
email:"my@email.com",
oldPassword:"mypassword",
newPassword:"otherpassword"
}).then(function(){
console.log("Passwordchangedsuccessfully!")
}).catch(function(error){
console.error("Error:",error)
})

$changeEmail(credentials)

Changestheemailofanexistinguserusinganemail/passwordcombination.Thisfunctionreturnsapromise
thatisresolvedwhentheemailhasbeensuccessfullychangedontheFirebaseAuthenticationservers.

$scope.authObj.$changeEmail({
oldEmail:"my@email.com",
newEmail:"other@email.com",
password:"mypassword"
}).then(function(){
console.log("Emailchangedsuccessfully!")
}).catch(function(error){
console.error("Error:",error)
})

Note:The $changeEmail() methodrequiresFirebase2.1.0orlater.

$removeUser(credentials)

Removesanexistinguseraccountusinganemail/passwordcombination.Thisfunctionreturnsapromisethatis
resolvedwhentheuserhasbeensuccessfullyremovedontheFirebaseAuthenticationservers.
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

21/22

11/2/2016

AngularFireArealtimebackendforAngularJSfromFirebase.

$scope.authObj.$removeUser({
email:"my@email.com",
password:"mypassword"
}).then(function(){
console.log("Userremovedsuccessfully!")
}).catch(function(error){
console.error("Error:",error)
})

Notethatremovingauseralsologsthatuseroutandwillthereforfireany onAuth() callbacksthatyouhave


created.

$resetPassword(credentials)

Sendsapasswordresetemailtotheowneroftheaccount,containingatokenthatmaybeusedtoauthenticate
andchangetheuserspassword.Thisfunctionreturnsapromisethatisresolvedwhentheemailnotificationhas
beensentsuccessfully.

$scope.authObj.$resetPassword({
email:"my@email.com"
}).then(function(){
console.log("Passwordresetemailsentsuccessfully!")
}).catch(function(error){
console.error("Error:",error)
})

BROWSERCOMPATIBILITY
Browser

VersionSupported

WithPolyfill

InternetExplorer

9+

9+(Angular1.3onlysupports9+)

Firefox

4.0

3.0?

Chrome

5?

Safari

5.1.4

Opera

11.6

Polyfillsareautomaticallyincludedtosupportolderbrowsers.See src/polyfills.js forlinksanddetails.

https://www.firebase.com/docs/web/libraries/angular/api.html#angularfirefirebasearrayaddnewdata

22/22

Você também pode gostar