notes - data stores - firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · this...

22
Notes - Data Stores - Firebase Dr Nick Hayward A general intro and outline for using Firebase with JavaScript based client-side and mobile apps. Contents intro what is Firebase? authentication cloud storage real-time database Firebase - basic setup Firebase - create real-time database Firebase - import JSON data Firebase - permissions add Firebase to JS based app add to index.html - initial usage JS based app - initial usage for web and cross-platform define DB connection ref() method write data write data - set all data write data - set data for a specific location Promises with Firebase remove data remove data - specify location remove data - all data remove data - set() with null Update data update data - existing properties update data - add new properties update data - remove properties update data - multiple properties at different locations update data - Promise chain read data read data - all data, once read data - single data, once read data - listener for changes - subscribe listener - why not use a Promise? read data - listener for changes - unsubscribe working with arrays JSON import - JS array issues Firebase push() method work with arrays - Firebase snapshot methods

Upload: others

Post on 25-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Notes-DataStores-FirebaseDrNickHayward

AgeneralintroandoutlineforusingFirebasewithJavaScriptbasedclient-sideandmobileapps.

Contents

introwhatisFirebase?

authenticationcloudstoragereal-timedatabase

Firebase-basicsetupFirebase-createreal-timedatabaseFirebase-importJSONdataFirebase-permissionsaddFirebasetoJSbasedapp

addto index.html -initialusage

JSbasedapp-initialusageforwebandcross-platformdefineDBconnectionref() method

writedatawritedata-setalldatawritedata-setdataforaspecificlocation

PromiseswithFirebaseremovedata

removedata-specifylocationremovedata-alldataremovedata- set() withnull

Updatedataupdatedata-existingpropertiesupdatedata-addnewpropertiesupdatedata-removepropertiesupdatedata-multiplepropertiesatdifferentlocationsupdatedata-Promisechain

readdatareaddata-alldata,oncereaddata-singledata,oncereaddata-listenerforchanges-subscribe

listener-whynotuseaPromise?

readdata-listenerforchanges-unsubscribe

workingwitharraysJSONimport-JSarrayissuesFirebase push() methodworkwitharrays-Firebase snapshot methods

Page 2: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

createarrayfromFirebasedata

addlistenersforFirebasevaluechangeslistenereventsfordatastoreupdateschild_removed eventchild_changed eventchild_added event

Intro

Atitsheart,FirebaseoffersahostedNoSQLdatabase.Particularlyusefultous,thisdatastoreisJSON-based,offeringquick,easydevelopmentfromwebvieworUIlogictodatastore.Itsyncsourapp'sdataacrossmultipleconnecteddevicesinamatterofmilliseconds,andisavailableforofflineusageaswell.

Ineffect,itprovidesanAPIforaccessingandqueryingtheseJSONdatastoresinreal-timeforallconnectedusers.

However,Firebaseasahostedoptionismorethanjustdatastoresandreal-timeAPIaccess.Ithasnowgrown,largelyoverthelastyearorso,toincludeadditionalfeaturesforanalytics,cloud-basedmessaging,appauthentication,filestorage,testoptionsforAndroid,notifications,adverts,andmuchmore...

Duetoitsscopeandoptions,Firebasehasbecomeanincreasinglypopularoptionforbothwebandmobileapps.

ManyofFirebase'spatternsandasyncquerystructureswillalsoworkwithotherdatastoreoptions.Usually,itwillonlytakefewchangeshereortheretoportyourcomponents.

WhatisFirebase?

So,whatisFirebase?

It'sahostedplatform,acquiredbyGoogle,whichprovidesvariousoptionsfordatastarage,dataaccess,andreal-timedatabasequerying.Forexample,weoftenconsidertheAuthentication,CloudStorage,andReal-timeDatabaseformanyJavaScriptbasedapps,bothwebandmobile,wenowbuild.

authentication

AuthenticationwithFirebaseprovidesvariousbackendservicesandSDKstohelpdevelopersmanageauthenticationforanapp.Thisservicesupportsmanydifferentproviders,includingFacebook,Google,Twitter&c.usingtheindustrystandardOAuth2.0andOpenIDConnectprotocols.

cloudstorage

CloudStorageiscustomarilyusedforuploading,storing,andthendownloadingfilesforappsandtheirusers.Italsofeaturesausefulsafetycheckifandwhenauser'sconnectionisbrokenorlost.Ineffect,itmonitorstheconnectionandprogresstohelpsavebandwidthandtime.FilesareusuallystoredinaGoogleCloudStoragebucket,whichmeansthattheyshouldbeaccessibleusingeitherFirebaseorGoogleCloud.So,wemaythenconsiderusingtheGoogleCloudplatformforimagefiltering,processing,orperhapsevenvideoencoding&c.SuchmodifiedfilesmaythenbecomeavailabletoFirebaseagain,andanyconnectedapps.

Forexample,Google'sCloudPlatform

real-timedatabase

TheReal-timeDatabaseoffersahostedNoSQLdatastorewiththeabilitytoquicklyandeasilysyncdata.Thisdatasynchronisationisactiveacrossmultipledevices,inreal-time,asandwhenthedataisupdatedintheclouddatabase.

Besidesthesebannerservices,Firebasealsooffersextrassuchasanalytics,advertisingservicessuchasadwords,crashreporting,notifications,andvarioustestingoptions.

Page 3: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

AllofthesemaybemonitoredandmaintainedfromtheFirebaseconsolewitharegisteredaccount.

Firebase-basicsetup

WecanstartusingFirebasebycreatinganaccountwiththeserviceusingastandardGoogleaccount,

Firebase

AfterloggingintoFirebase,youmaytheneitherviewtheGetStartedmaterialorsimplynavigatetotheFirebaseconsole.ThisiswherewecanmonitorandsetconfigurationsforFirebase.

AttheConsolepage,wecanthengetstartedbycreatinganewproject.Simplyclickontheoptionto Addproject ,andenterthenameofthisnewproject,andselectaregion.

You'llthenberedirectedtotheconsoledashboardpageforthenewproject.Thisisprimarilywhereweaccessthevariousoptionsforeachproject,andgenerallycontrolandmaintainourproject'sstructureandsetup.

DocumentationfortheFirebaseReal-Timedatabaseisasfollows,

https://firebase.google.com/docs/reference/js/firebase.database

Firebase-createreal-timedatabase

WecannowsetupadatabasewithFirebaseforatestJavaScriptbasedapp,includingwebandcross-platformmobile.

StartbyselectingtheDatabaseoptionfromtheleftsidebarontheConsoleDashboard.It'savailableundertheDEVELOPoption.Then,simplyselectGetStartedforthereal-timedatabase.

Thiswillthenpresentanemptydatabasewithanappropriatenametomatchthecurrentproject.Thisnameis,asyoumightexpect,derivedfromtheprojectnameandID.

DatawillbestoredinausefulJSONformatinthereal-timedatabaseonFirebase,soitshouldbefamiliarformostdevelopers.WealsoseesimilarpatternswithotherNoSQLdatastoressuchasMongoDB.

Ingeneral,workingwithFirebaseissimple,andformostexamplesit'salsostraightforwardtouse.It'salsopossibletogetstartedquicklydirectfromtheFirebaseconsole,orsimplyimportsomeexistingJSONforyourproject'sdata.

Image-Firebase

createadatabase

Page 4: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Firebase-importJSONdata

So,wemightstartwithsomesimpledatatohelptestFirebasewithaJavaScriptbasedapp.Wecanimportthefollowingintoourtestdatabase,andthenquerythedata&c.fromtheapp.

{"egypt":{"code":"eg","ancient_sites":{"abu_simbel":{"title":"abusimbel","kingdom":"upper","location":"aswangovernorate","coords":{"lat":22.336823,"long":31.625532},"date":{"start":{"type":"bc","precision":"approximate","year":1264},"end":{"type":"bc","precision":"approximate","year":1244}}},"karnak":{"title":"karnak","kingdom":"upper","location":"luxorgovernorate","coords":{"lat":25.719595,"long":32.655807

Page 5: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

},"date":{"start":{"type":"bc","precision":"approximate","year":2055},"end":{"type":"ad","precision":"approximate","year":100}}}}}}

InFirebase,thisJSONwillbestoredasfollows,

Image-Firebase

JSONimport

Page 6: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Firebase-permissions

Oneofthethingsyou'llnoticewhenyouinitiallycreateadatabasewithFirebaseisapersistentnotificationconcerningDefaultsecurityrulesrequireuserstobeauthenticated.WehavetheoptiontoeitherLEARNMOREorDISMISSthisnotification.

However,it'sworthconsidering,foramoment,howpermissionsaremanagedwithFirebase.

WecanmanagedatabaseaccessforourusersastheyloginandauthenticatewiththeFirebaseservice.Therearemanyoptionsavailableforpermissions,e.g.

Page 7: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Firebase-databaserules

butafewwemayconsidertogetusstarted.Forexample,ifweclicktheRULEStabwecanmodifyourrulestopermitaccesstothedatawithoutauthentication.Thiswill,ofcourse,helpusinitiallytestourapppriortoaddinganyrequiredauthentication.

So,wemodifytherulesasfollows.From,

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

to

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

AddFirebasetoJSbasedapp

WecannowtestournewFirebasedatabasewithaJavaScriptbasedapp.

WeneedtostartbygettingsomeusefulinformationfromFirebase,inparticularbyselectingtheoptionfromtheconsoletoAddtoapp.

SelecttheProjectOverviewlinkintheleftsidebar,andthenclickontheiconforAddapp.

ThiswillshowoptionsforAndroidandiOSnative,plusJavaScript.

We'renotlimitedtousingFirebasewithjustaJSbasedwebapp,butwecantakeadvantageoftheprovidedJavaScriptSDKwithotheroptionssuchasApacheCordova,ReactNative,andwebdevelopment&c.

TheFirebaseconsolewillshowusamodalwithinitialisationsettingsforaddingFirebaseusagetoourapp.

Forexample,we'llgetthefollowingsampleconfigforourtestdatabase.

Image-Firebase

initialisationconfigsettings

Page 8: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Wecanstartbycopyingtheseconfigvaluesforusewithourapp.

addto index.html -initialusage

We'llstartbytestingthissetupwiththedefaultconfiginour index.html file.

e.g.

<!--JS-Firebaseapp--><scriptsrc="https://www.gstatic.com/firebasejs/5.5.4/firebase.js"></script><script>//InitializeFirebasevarconfig={apiKey:"YOUR_API_KEY",authDomain:"422cards.firebaseapp.com",databaseURL:"https://422cards.firebaseio.com",projectId:"422cards",storageBucket:"422cards.appspot.com",messagingSenderId:"282356174766"};firebase.initializeApp(config);</script>

ThisexampleincludesinitialisationinformationsotheSDKhasaccessto

AuthenticationCloudstorageRealtimeDatabaseCloudFirestore

n.b.don'tforgettomodifytheabovevaluestomatchyourownaccountanddatabase...

Page 9: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

However,it'salsopossibletocustomiserequiredcomponentsperapp.Thisallowsustoincludeonlythefeaturesrequiredforeachapp.Forexample,theonlyrequiredcomponentis

firebase-app -coreFirebaseclient(requiredcomponent)

<!--FirebaseAppisalwaysrequiredandmustbefirst--><scriptsrc="https://www.gstatic.com/firebasejs/5.5.4/firebase.js"></script>

Then,wemayaddamixofthefollowingoptionalcomponents,

firebase-auth -variousauthenticationoptionsfirebase-database -realtimedatabasefirebase-firestore -cloudFirestorefirebase-functions -cloudbasedfunctionforFirebasefirebase-storgae -cloudstoragefirebase-messaging -Firebasecloudmessaging

<!--Addadditionalservicesthatyouwanttouse--><scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-auth.js"></script><scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-database.js"></script><scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-firestore.js"></script><scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-messaging.js"></script><scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-storage.js"></script>

<scriptsrc="https://www.gstatic.com/firebasejs/5.5.3/firebase-functions.js"></script>

Then,asnotedintheaboveinitialexample,wedefineanobjectforthe config oftherequiredservicesandoptions,

varconfig={//addAPIkey,services&c.};firebase.initializeApp(config);

JSbasedapp-initialusageforwebandcross-platform

Afterdefiningtherequiredconfigandinitialisation,wecanthenstarttoaddtherequiredlistenersandcallstoaJS-basedwebapporcross-platformmobileapp.

defineDBconnection

WecanestablishaconnectiontoourFirebaseDBasfollows,

constdb=firebase.database();

Wemaythenusethisreferencetoconnectandqueryourdatabase.

ref() method

Oncewehavetheconnectiontothedatabase,wemaythencallthe ref() ,orreference,method.

Weusethismethodtoread,write&c.datainthedatabase.

Bydefault,ifwecall ref() withnoarguments,ourquerywillberelativetotherootofthedatabase.Ineffect,we'llbereading,writing&c.relativetothewholedatabase.

Page 10: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Wemayalsorequestaspecificreferenceinthedatabasebypassingalocationpath,e.g.

db.ref('egypt/ancient_sites/abu_simbel/title').set('Abydos');

Thisexamplewillrequestareferencetothe title propertyinthespecifiedobjectrelativetothedatastoreroot.Wemaythenusethisreference,forexample,to set anewvalue.

Aswefindwithotherdatabases,suchastablesinSQLorcollectionsinMongoDB&c.,thisallowsustocreatemultiplepartsoftheFirebasedatabase.Suchpartsmightincludemultipleobjects,properties,andvalues&c.

Thisbecomesaquickandeasyoptionfororganisinganddistributingdatawithinthedatabase.

Writedata

Wemayalsowritedatatotheconnecteddatabase,againfromaJavaScriptbasedapplication.

FirebasesupportsmanydifferentJavaScriptdatatypes,including

stringsnumbersbooleansobjectsarrays...

Ineffect,anyvaluesanddatatypeswemaycustomarilyaddtoaJSONobject.However,it'sworthnotingthatFirebasemaynotmaintainthenativestructureuponimport.Arrays,forexample,willbeconvertedtoplainJavaScriptobjectsinFirebase.

writedata-setalldata

Wecan set dataforthewholedatabasebycallingthe ref() methodattheroot.

e.g.

db.ref().set({site:'abu-simbel',title:'AbuSimbel',date:'c.1264B.C.',visible:true,location:{country:'Egypt',code:'EG',address:'aswan'}coords:{lat:'22.336823',long:'31.625532'}});

So,thisexamplewillnowsetthedataforthewholedatabasetotheobjectpassedastheargumenttothe set()method.

However,thedatapasseddoesnothavetobeanobject.Wemaypassanyoftheabovesupporteddatatypes.

n.b.whenwecall set() relativetojusttheroot,theexistingdatawillbeoverwritten.Ineffect,thecurrentdatabaseisdeleted,andthepassedobjectbecomesthenewdatabase.

Page 11: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

writedata-setdataforaspecificlocation

Aswithreadingspecificdata,wemayalsowritedatatoaspecificlocationinthedatabase.

Again,weaddanargumenttothe ref() methodspecifyingtherequiredlocationinthedatabase.

e.g.

db.ref('egypt/ancient_sites/abu_simbel/location').set('nearaswan');

ref() maybecalledrelativetoanydepthinthedatabasefromtheroot,therebyallowingustoupdateanythingfromthewholedatabasetoasinglepropertyvalue.

PromiseswithFirebase

FirebaseincludesnativesupportforPromisesandassociatedchains.

ThismeanswedonotneedtocreateourowncustomPromises.Instead,wemayworkwithareturnPromiseobjectfromFirebaseusingastandardchain.

Forexample,whenwecallthe set() method,FirebasewillreturnaPromiseobjectforthemethodexecution.

The set() methodwillnotexplicitlyreturnanythingexceptforsuccessorerror.Thismeanswecansimplycheckthereturnpromiseasfollows,

db.ref('egypt/ancient_sites/abu_simbel/title').set('AbuSimbel').then(()=>{//logdatasetsuccesstoconsoleconsole.log('dataset...');}).catch((e)=>{//catcgerrorfromFirebase-errorloggedtoconsoleconsole.log('errorreturned',e);});

Removedata

Asexpected,wherewecanaddnewdatatothedatabase,wemayalsodeleteandremovedatafromtheconnecteddatabase.

removedata-specifylocation

Aswithsettingdata,wemayalsodeletedataataspecificlocationintheconnecteddatabase.

e.g.

db.ref('egypt/ancient_sites/abu_simbel/kingdom').remove().then(()=>{//logdataremovedsuccesstoconsoleconsole.log('dataremoved...');}).catch((e)=>{//catcgerrorfromFirebase-errorloggedtoconsoleconsole.log('errorreturned',e);});

So,weneedtogetareferencetothespecificlocationinthedatabase,andthenexecutethe remove() methodforthatdata.Thiswilldeletethespecificpropertyanddatavalue.

Page 12: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Wemayalsochainastandard then() and catch() methodtothereturnPromiseobject.

removedata-alldata

Wemayalsoremoveallofthedataintheconnecteddatabase.

e.g.

db.ref().remove().then(()=>{//logdataremovedsuccesstoconsoleconsole.log('dataremoved...');}).catch((e)=>{//catcgerrorfromFirebase-errorloggedtoconsoleconsole.log('errorreturned',e);});

Aswecanseeinthisexample,wesimplyneedtocallthe ref() methodrelativetotherootoftheconnecteddatabase.Thiswilleffectivelywipeallofthecurrentdata.

removedata- set() withnull

AnotheroptionspecifiedintheFirebasedocsfordeletingdataisbyusingthe set() methodwitha null value.

e.g.

db.ref('egypt/ancient_sites/abu_simbel/kingdom').set(null).then(()=>{//logdataremovedsuccesstoconsoleconsole.log('datasettonull...');}).catch((e)=>{//catcgerrorfromFirebase-errorloggedtoconsoleconsole.log('errorreturned',e);});

(n.b.Whilstthisoptionworks,itseemsapooruseofthe set() method.Itisalsoapooruseofthe null datatype,whichisanobjecttypeinJavaScript.Thiscallis,therefore,reliantonFirebaseinterpretinga null valueanddatatypeasaremoverequesttothedatabase.)

Wemay,however,needtousethispatternwiththefollowing update() method.

Updatedata

Wemayalsocombinesettingandremovingdatainasinglepatternbyusingthe update() methodcalltothedefineddatabasereference.

The update() methodis,therefore,meanttobeusedtoupdatemultipleitemsinthedatabaseinasinglecall.Thismeanswemustpassanobjectastheargumenttothe update() method.

updatedata-existingproperties

So,ifwewantedtoupdatemultipleexistingpropertieswemighthavethefollowingexample,

db.ref('egypt/ancient_sites/abu_simbel/').update({title:'ThetempleofAbuSimbel',visible:false

Page 13: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

});

updatedata-addnewproperties

Wemayalsoaddanewpropertyforthespecificlocationinthedatabase,

db.ref('egypt/ancient_sites/abu_simbel/').update({title:'ThetempleofAbuSimbel',visible:false,date:'c.1264B.C.'});

So,wemaynowsetnewvaluesforthetwoexistingproperties, title and visible ,andaddanewpropertyandvaluefor data .

Abenefitofthe update() methodisthatitwillonlyupdatethespecificproperties,andnotoverrideeverythingatthereferencelocationaswiththe set() method.

updatedata-removeproperties

Wemayalsocombinetheseupdateswiththeoptiontoremoveanexistingproperty,

e.g.

db.ref('egypt/ancient_sites/abu_simbel/').update({card:null,title:'ThetempleofAbuSimbel',visible:false,date:'c.1264B.C.',});

Aswithpassing null tothe set() method,we'reeffectivelydeletingthespecifiedpropertyfromthereferencelocationinthedatabase.

Therefore,we'renowabletocombinecreatinganewpropertywithupdatinganddeletinganyexistingpropertiesatthedefinedreferencelocation.

updatedata-multiplepropertiesatdifferentlocations

Wemayalsocombineupdatingdatainmultipleobjectsatdifferentlocationsrelativetotheinitialpassedreferencelocation.

e.g.

db.ref().update({'egypt/ancient_sites/abu_simbel/visible':true,'egypt/ancient_sites/karnak/visible':false});

Relativetotherootofthedabatase,we'venowupdatedmultiple title propertiesindifferentcards.

Thepropertyname,e.g. egypt/ancient_sites/abu_simbel/visible ,isinterpretedbyFirebaseasalocationinthedatabaserelativetothepassedrootreference.

n.b.thispatternofupdateisonlyrelativetothecurrentpathspecifiedintheargumentpassedtothe ref() method.Therefore,onlychildpropertiesofthecurrentlocationmaybeupdatedusingthispattern.Thisisduetocharacterrestrictionsonthepropertyname.e.g.thenamemaynotbeginwith . , / &c.

updatedata-Promisechain

Page 14: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

The update() methodwillalsoreturnaPromiseobject,whichallowsustochainthestandardmethods.

e.g.

db.ref().update({'egypt/ancient_sites/abu_simbel/visible':true,'egypt/ancient_sites/karnak/visible':false}).then(()=>{console.log('updatesuccess...');}).catch((e)=>{console.log('error=',e);});

Aswith set() and remove() ,thePromiseobjectitselfwillsimplyreturnsuccessorerrorforthemethodcall.

Readdata

Wecanfetchdatafromtheconnecteddatabaseinmanydifferentways,includingallofthedataorasinglespecificpartofthedata.

Wemayalsoconnectandretrievedataonce,orsetupalistenerforpollingthedatabaseforliveupdates.

readdata-alldata,once

e.g.toretrievealldatafromthedatabaseasingletime,

//ALLDATAONCE-requestalldataONCE//-returnsPromisevaluedb.ref().once('value').then((snapshot)=>{//snapshotofthedata-requestthereturnvalueforthedataatthetimeofquery...constdata=snapshot.val();console.log('data=',data);}).catch((e)=>{console.log('errorreturned-',e);});

So,wecannowreturnallofthedatastoredinthedatabaseatthetimeofthisquery.i.e.asnapshotofthecurrentstateofthedatabase.

readdata-singledata,once

Likewise,wemayquerythedatabaseonceforasinglespecificvalue.

e.g.

//SINGLEDATA-ONCEdb.ref('egypt/ancient_sites/abu_simbel/').once('value').then((snapshot)=>{//snapshotofthedata-requestthereturnvalueforthedataatthetimeofquery...constdata=snapshot.val();console.log('singledata=',data);}).catch((e)=>{console.log('errorreturned-',e);});

So,thiswillreturnthevalueforthecardatlocation egypt/ancient_sites/abu_simbel/ .

Page 15: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

readdata-listenerforchanges-subscribe

Wemayalsosetuplistenersforchangestotheconnecteddatabase,whichwillthencontinuetopolltheDBforanysubsequentchanges.

e.g.

//LISTENER-pollDBfordatachanges//-anychangesinthedatadb.ref().on('value',(snapshot)=>{console.log('listenerupdate=',snapshot.val());});

Byusingthe on() method,we'reabletosetupalistenerthatpollstheDBforanychangesin value .Asbefore,wemaythengetthecurrentsnapshotvalueforthedatastored.

Ifwechangeanydataintheonlinedatabase,thislistenerwillautomaticallyexecutethedefinedsuccesscallbackfunction.

Wemayalsoaddsomeinitialerrorhandlingforthesubscriptioncallback,e.g.

//LISTENER-SUBSCRIBE//-pollDBfordatachanges//-anychangesinthedatadb.ref().on('value',(snapshot)=>{console.log('listenerupdate=',snapshot.val());},(e)=>{console.log('errorreadingdb',e);});

listener-whynotuseaPromise?

Asthelistenerisnotifiedofupdatestotheonlinedatabase,weneedthecallbackfunctiontobeexecuted.Infact,wemayneedittobeexecutedmultipletimesformanyupdatestothestoreddata.

However,aPromisemayonlyberesolvedasingletimewitheither resolve or reject .So,ineffect,wewouldneedtoinstantiateanewPromiseforeachupdate.Thiswouldnotworkasexpected,whichiswhyweuseastandardcallbackfunction.

ThecallbackmaysimplybeexecutedeachandeverytimethereisanupdatetotheDB.

readdata-listenerforchanges-unsubscribe

Wemayalsoneedtounsubscribefromallorspecificchangesintheonlinedatabase.Forexample,ausermaynavigatetoadifferentscreenortheapplicationispausedinthebackground.

e.g.

db.ref().off();

ThiswillremoveallcurrentsubscriptionstothedefinedDBconnection.

However,wemayalsounsubscribeaspecificsubscriptionbysimplypassingthecallbackweusedfortheoriginalsubscription.

So,wemayabstractthecallbackfunctionandpassittoboththe on() and off() methodsforthedatabaseref() method.

e.g.

Page 16: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

//abstractcallbackconstvalChange=(snapshot)=>{console.log('listenerupdate=',snapshot.val());};

Wemaythensimplypassthisvariableasthecallbackargumentforbothsubscribeandunsubscribeevents.

e.g.

//subscribedb.ref().on('value',valChange);//unsubscribedb.ref().off(valChange);

ThiswillallowourapptomaintaintheDBconnection,andunsubscribeaspecificsubscription.

workingwitharrays

Firebasedoesnotexplicitlysupportarraydatastructures.Instead,itwillconvertarrayobjectstoplainJavaScriptobjects.Thiswillnegatethebuilt-initeratorforanarrayobject,therebydefiningplainobjectsinthestoredJSONdata.

JSONimport-JSarrayissues

Forexample,ifweimportthefollowingJSON

{"cards":[{"visible":true,"title":"AbuSimbel","card":"templecomplexbuiltbyRamessesII"},{"visible":false,"title":"Amarna","card":"capitalcitybuiltbyAkhenaten"},{"visible":false,"title":"Giza","card":"Khufu'spyramidontheGizaplateauoutsideCairo"},{"visible":false,"title":"Philae","card":"templecomplexbuiltduringthePtolemaicperiod"}]}

InFirebase,thisJSONwillbestoredasfollows,

Image-Firebase

JSONimport

Page 17: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

Eachindexvaluewillnowbestoredasaplainobjectwithanauto-incrementvaluefortheproperty.

e.g.

cards:{0:{card:"templecomplexbuiltbyRamessesII",title:"AbuSimbel",visible:"true"}}

So,wemaystillaccesseachindexvaluefromtheoriginalarrayobjectbutwithouteasyaccesstopre-defined,knownuniquereferences.

Forexample,toaccessthetitlevalueofagivencard,wewouldneedtoknowitsauto-generatedpropertyvalueinFirebase.

db.ref('cards/0')

Thisreferencewillbethepathtotherequiredobject,andwemaythenaccessagivenpropertyontheobject.

So,evenifweaddauniquereferencepropertytoeachcardwemaynotuseitwithoutknowingthepropertyvalueassignedtothecardbyFirebase.

Firebase push() method

ToaddnewcontenttoanexistingFirebasedatastore,wemayusethe push() methodtoaddthisdata.

Asthedataisaddedtothedatabase,auniquepropertyvaluewillbeauto-generated.

Page 18: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

e.g.

//pushnewdatatospecificreferenceindbdb.ref('egypt/ancient_sites/').push({"philae":{"kingdom":"upper","visible":false}});

ThisnewdatawillbeaddedtotheconnectedDB,butitwillbecreatedwithanauto-generatedIDfortheparentobject,e.g.

LPcdS31H_u9N0dIn27_

Thismaybeusefulfordynamiccontentthatispushedtoadatastore,e.g.

notes,tasks,calendardates&c.

Ineffect,wemayusethisauto-generateduniquereferencewhilstiteratingovertheexistingDBcontent.

So,asweiteratethroughthedatastoreandoutputthecontent,wemayaddareferencetotheauto-generatedIDforfuturereferenceandlookup.Thisreferencemaybestoredinalocaldatastructure,UIcomponentorelement,variablevalue,&c.

workwitharrays-Firebase snapshot methods

DatasnapshotmethodsinFirebasedocumentation.

Acommonlyusedmethodwith snapshot isthe val() method,whichwe'vealreadyusedmanytimesalready.

However,therearemanyadditionalmethodsspecifiedintheAPIdocumentationforDataSnapshot.

forEach() -iteratorforplainobjectsfromFirebase

createarrayfromFirebasedata

AswestoredataasplainobjectsinFirebase,weneedtoconsiderhowwemayworkwitharray-likestructuresfortechnologiesandpatternsthatrequirearraydatastructures,suchasRedux.

Ineffect,wemaygetthedatafromFirebase,andthenprepareitforuseasanarray.

Forexample,tohelpusworkwithFirebaseobjectdataandarrays,wemaycallthe forEach() methodonthereturnsnapshot .ThiswillprovidearequirediteratorfortheplainobjectsstoredinFirebase.

e.g.

//getrefindbonce//callforEach()onreturnsnapshot//pushvaluestolocalarray//uniqueidforeachDBparentobjectis`key`propertyonsnapshotdb.ref('egypt/ancient_sites').once('value').then((snapshot)=>{constsites=[];snapshot.forEach((siteSnapshot)=>{sites.push({id:siteSnapshot.key,...siteSnapshot.val()});});

Page 19: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

console.log('sitesarray=',sites);});

So,we'reabletoiteratethroughthereturnsnapshotvaluefortheconnectedDB.WemaythenpushselectedvaluestoeithercustompropertiesorusetheexistingpropertiesintheDB.

Inthisexample,wesetaspecificIDvalueinthearray,andthenusethespreadoperatortosimplyaddtheexistingpropertiesandvaluesfromthedatabasetothelocalarraydatastructure.

Forexample,wemayreturnthefollowing

Image-Firebase

snapshot forEach() -creatingalocalarray

Page 20: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

So,wenowhavealocalarrayfromtheFirebaseobjectdata,whichwemaythenusewithoptionssuchasRedux.

AddlistenersforFirebasevaluechanges

Aswemodifyobjects,properties,values&c.inFirebase,wemaysetlistenerstoreturnnotificationsforsuchupdates.

So,thereshouldbeanotificationforagivenupdaterelativetothedatastore.

e.g.wemayaddasinglelistenerforanyupdaterelativetothefulldatastore

Page 21: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

//LISTENER-SUBSCRIBE-v.2//-getalldata&thenpushreturndatatolocalarray...db.ref('egypt').on('value',(snapshot)=>{constsites=[];snapshot.forEach((siteSnapshot)=>{sites.push({id:siteSnapshot.key,...siteSnapshot.val()});});console.log('sitesarrayafterupdate=',sites);});

Asnotedearlier,the on() methoddoesnotreturnaPromiseobjectsoweneedtodefineacallbackforthereturndata.

listenereventsfordatastoreupdates

FirebaseprovidesafewdifferenteventsrelativetosubscriptionsandFirebaseupdates.

Forthe on() method,wemayinitiallyconsultthefollowingdocumentation,

on() eventsinFirebasedocs=https://firebase.google.com/docs/reference/js/firebase.database.Reference#on

Then,wemaytestvariouslistenersfordatastoreupdates.

child_removed event

Wemayaddasubscriptionforeventupdatesasachildobjectisremovedfromthedatastore.

The child_removed eventmaybeaddedasfollows,

//-listenforchild_removedeventrelativetocurrentrefpathinDBdb.ref('egypt/ancient_sites/').on('child_removed',(snapshot)=>{console.log('childremoved=',snapshot.key,snapshot.val());});

child_changed event

Likewise,wemayalsolistenforthe child_changed eventrelativetothecurrentpathpassedto ref() .

e.g.

//-listenforchild_changedeventrelativetocurrentrefpathinDBdb.ref('egypt/ancient_sites/').on('child_changed',(snapshot)=>{console.log('childchanged=',snapshot.key,snapshot.val());});

child_added event

Anothercommoneventisaddinganewchildtothedatastore.Forexample,ausermaycreateandaddanewnoteorto-doitem.

e.g.

//-listenforchild_addedeventrelativetocurrentrefpathinDBdb.ref('egypt/ancient_sites/').on('child_added',(snapshot)=>{console.log('childadded=',snapshot.key,snapshot.val());});

Page 22: Notes - Data Stores - Firebasecsteach422.github.io/assets/docs/extras/ds-firebase-guide.pdf · This will show options for Android and iOS native, plus JavaScript. We're not limited

References

Firebase-https://firebase.google.com/FirebaseJSGuide-https://firebase.google.com/docs/web/setupFirebaseJSReference-https://firebase.google.com/docs/reference/js/FirebaseJS on() events-https://firebase.google.com/docs/reference/js/firebase.database.Reference#on