Realtime Web Apps with AngularJS and Firebase

Realtime Web Apps with AngularJS and Firebase


>>GREEN: So I’m Brad Green. I’m the manager
of AngularJS. Thanks again for coming. Tonight, we’ve got a special guest. It’s not just one
of our normal presentations about something from the Angular team, it’s actually from
a team that we’re very excited about, Firebase. Not just here from the Firebase team, he’s
come to present on how–a little bit of how Firebase works and how it can work with an
Angular app in a real-time situation. Anant before Firebase, worked at Mozilla and did
super exciting things, maybe he’ll share some stories afterwards. But now, let’s just welcome
him talking about Firebase and real-time apps with Angular.
>>NARAYANAN: Thanks Brad and the Angular team for hosting me today. And thank you all
for coming. I’m really excited to be here, and I’m going to just dig in. Let’s see where
are the slides are, can you guys see them? I think we got–all right, there we go. Cool.
So today, I’m going to talk about Angular and Firebase. So for those of you who don’t
know what Firebase is, I’ll dig in a little bit about that, and then, we’ll discuss how
you can use Firebase along with AngularJS to not have to write a backend for your AngularJS
app. So as we know, Angular is great at writing the front-end but a lot of the time, web apps
need to also have a backend to kind of persist app data, and we’ll dig in to how Firebase
can make that really, really easy for you. So that’s what the talk is going to cover.
So first of all, I’ll dig in a little bit about what Firebase is, what the basics of
Firebase are, and then the role of a backend and an Angular app and how Firebase can help
out with that. And then, we’ll do a little bit of code–writing code together, we’ll
write a simple to-do app because that’s what everyone writes when they first learn something
new. That uses Firebase with AngularJS to make a collaborative to-do app that multiple
people can use and hopefully we’ll get you guys to participate there as well. And finally,
we’ll touch a little bit about user authentication, and I wanted to cover that topic because one
of the things–one of the challenges about writing client-side apps only is security
and user authentications. So I’ll talk a little bit about how that works in a Firebase world.
So, let’s get started. Firebase is a real-time synchronization network. So what that means
is, it is primarily a data store that can host your apps data, but the changes to that
data are propagated everywhere in real-time. So, what that means is not only do you use
it to store your apps data, but whenever you change the apps–the data that is stored,
all your other clients are instantly notified or near instantly notified in real-time. So,
not only can you use it as a data persistent system, but also for message passing by virtue
of changing data. It acts as both a message bus as well as a–as a persistence layer.
I wanted to talk a little bit about why we chose to do it that way. Well, you have a
lot of services that are purely focused on messaging and push notifications and so forth,
but what we noticed was when you are writing an app, you also almost always want to persist
that data. So by doing message passing, we’ve seen apps where you’re archiving messages,
what happens when you miss the messages, the client needs to catch up when they’re offline.
It is just a more complex way of thinking of things when all your–when all your app
really needs is a place to store data and then get notified when that data changes.
So by combining message passing with persistence, you get something–you get something like
Firebase. So, when you combine that with a security system that we will dig in to towards
the end of the talk, what you’ll get is a complete backend. So, what this means is all
you need is a front-end code that includes the Firebase JavaScript library, and you don’t
have to worry about any server code or running servers or writing backends or any of that
stuff because Firebase is the backend because most apps, all they need to do is take data
from here, put it over there, take data from here, and put it over there. That’s essentially
what many, many apps end up doing. So I’m going to show a little demo here just to see–just
to show you what Firebase is capable of. So, right here, we have two canvas elements on
the left and the right and they’re both in IFrame, so they’re–as if they’re loaded in
two different browsers. And when I draw here, you’ll see that the canvas on the right-hand
side is getting updated instantly. So, the way that happens is, you take–we attach the
listeners to the canvas and whenever I draw a pixel there, the data is being stored in
Firebase and then the other client is getting a notification that data has now appeared
in the Firebase because they’re listening for it, and then it paints a pixel on that
side. And so, if I do it the other way, it works as well. And as you can see, merge conflicts
are all reasonably–so you can draw over each other and last strike wins, we have more sophisticated
merge mechanisms if required. I’ll walk into those details, but it is possible. We try
to keep things as simple as possible and it works really great for 99% of applications.
One thing I do want to show here is–let me open up what we call the Firebase Forge, which
is a graphical debugger for the data that is stored in Firebase. So, all data in Firebase
is represented by URL. So, in this case, it’s hiw-randomstring.firebaseiodemo.com. So that’s
the–that’s the URL that the canvas example is going to. And when I make changes there,
you see data is appearing here. So let’s take a look at that. Let me get out of the full
screen here. I’m going to clear the canvas. Make a note of what happens in Forge. So all
the data disappears because I just cleared the canvas. And then–and as I’m drawing stuff,
you’ll see new data appear. So it’s really simple how we represent this data, so it’s,
you know, x and y coordinate and then the color, because in a full-fledged drawing example,
we have other colors as well. But here, it’s just yellow and x and y coordinate. And then,
whenever I make any changes, you’ll see–you’ll see the updates appear here. And then when
I clear the canvas, the data gets cleared. So this is the easiest way to kind of visualize
what the role of Firebase is. It’s a data store, but not only a data store, when you
change the data, all clients are instantly notified of the change so that they can react
appropriately. So that’s Firebase. So you can do more than just like drawing apps with
Firebase. So on the Angular homepage, we actually power one of the examples here where it says
wire up a backend. So this is an example of AngularFire in action. And AngularFire is
a JavaScript include that you can drop in, so you can see it right here. Along with Firebase.js,
you drop in AngularFire.js. It is a binding that helps you easily synchronize Angular
models to Firebase, which means that whenever an Angular model changes in one place, it
also changes in Firebase which will then trigger the same model if you had bounded in other
clients being updated instantly as well. So in this particular case, it powers the homepage.
So, whenever someone adds a JavaScript project–and you can try this out. So, if you go to angularjs.com
on your thing and add a project here, you’ll see that it instantly appears here. And the
way that it works is, it persists the data of the Firebase and then a callback gets figured
here which updates the model, which then updates the DOM thanks to Angular’s two-way binding.
So just like how Angular synchronizes the DOM with models in memory via the two-way
data binding, AngularFire will synchronize the models in memory with Firebase as a two-way
data binding. So you get kind of, like, a three-way data binding. And then if you have
multiple clients talking to the same Firebase, then everybody is at the same state pretty
much. Oops. So that’s what happens. So similarly, if I open up the Forge for this, which is
angularjs-projects.firebaseio.com, you can see someone just added something so–or–oh,
they added awesome at the end. So you can see that being reflected over here. So you
can see the awesome got appended there because someone just edited it. So that’s exactly
how it works. So it functions as a backend for your–for your web app. So, like I mentioned,
so this is a–an image I just stole from the Angular presentation of Google I/O, which
really explains how the two-way data binding works. So, whenever there’s changes in the
DOM, they reflect in memory, and whenever there’s changes in memory, they reflect in
the DOM. So just a quick refresher, I’m sure many of you are already familiar with Angular,
but over here, I’m saying input type text, engine model equals name. So I’m binding the
contents of that input element to a model called–and then I’m reusing the model here
to say hi, name. So whenever I change this, the h1 element also gets updated because of
Angular’s binding, right? Now, with AngularFire, we extend this synchronization to a cloud
database. So, we take a model that is in memory on one of the clients and then store that
data in Firebase, and then whenever it changes, we send the changes back so that the model
is always up to date. So, the result of that is if I–so this is almost exactly the same
code as before, except now, we included angularfire.js, and then we added some code. So why don’t
we go through what the code says. So I created a module and I added Firebase as a dependency.
So Firebase is a module that’s provided by angularfire.js, and then in my controller,
I define the dependency on AngularFire. And now, I’m going to use that object to create
a binding between some data that is on a Firebase somewhere, and as we mentioned before, all
data in Firebase is represented by a URL. So in this case, it’s anant.firebaseio.com/angular,
just something I came up for this demo. And then I say AngularFire, you know, bind this
URL to scope.name. And the last argument there is the type. So, I’m saying this is going
to be a string because that’s what this is. So now–let me go back to that. I’m going
to come out of full screen and–now when I say [INDISTINCT] the Angular’s part is working
just as normal like it’s synchronizing, but the difference is, if I open this in another
browser, so let’s open Firefox here. So this is another browser. It could halfway across
the world, it doesn’t matter, but because the change is–or the data is being stored
in Firebase–oops. There you go. So you can see [INDISTINCT] over here as well. And I’m
going to open this URL. So I’m going to copy this URL over here and paste it in here. And
you can see the data is here. Now, any place I change the data, it’s going to reflect in
the other two places. So if I changed this to everyone, you can see that it updated in
Firefox but it also updated it in Firebase Forge. Similarly, if I clear the data here,
it gets reflected in both places. So with just a couple lines of code, we have taken
a model–so this is kind of a big deal. So think about it. Just with a couple of lines
of code, we’ve done–we have extended the two-way synchronization between just a single
client to many, many clients, and you can have hundreds of thousands of these files
and it will all scale up–you don’t have to worry about scaling it up or anything like
that, because you’re using Firebase as the backend. We’ll take care of making sure that,
you know, all the users that–user website are taken care of. So, this has traditionally
been really hard to do. So, think about what you would have to do if you didn’t have Firebase
to implement this kind of a real time update. So, if you–if you entered something, you
have to listen for changes and Angular will help you with a little bit of that, you can
use scope.watch or something to know where there are changes. And every time that change
happens, you’ll have to efficiently update the server via some REST API, so you’ll have
to come up with some API to represent all of these changes. Then you’ll have to implement
the REST API by writing, you know, a Node.js server, Ruby Rails, or something on the server
side, write a whole bunch of server code. And then have that server be scalable to thousands
of clients depending on how popular your app is. And then have each of your clients then
watch for changes, either by long polling the REST API or creating some kind of WebSocket
protocol on your own. So, there’s just a ton of work that needs to go behind doing this
kind of thing. But with Firebase, you just go to Firebase.com, you sign up for a Firebase,
you drop an Angularfire.js in your–as a dependency in your app and with just a couple lines of
code, all the stake can be synchronized. Okay. So, let’s–now that we’ve done that. Let’s
do a little bit–something a little bit more complex. So, that’s just synchronizing a single
string across multiple clients. So, that by itself is kind of hard to do if you had to
do it from scratch, but let’s see what Firebase is capable of. Something a little bit more
than that. So, when I say complex, I’m not going to go super complex. We’ll pick a to-do
app, because that’s what everyone does. And we’ll pick a to-do app that someone else has
already written. It’s called TodoMVC. Some of you might be familiar with this. So, it’s
just a to-do app that’s written in a bunch of different frameworks and of course Angular
is one of them. So, what we’re going to do is take the Angular TodoMVC example. And then
coordinate to be collaborative, so that multiple people can add to-do items at the same time
and see what other people have added. And also I have the state of each to-do item synchronized
across all clients. So, if I completed a to-do item, then I want that state to be synchronized
as well. So, let’s just dig in to some code here. So, I’ve already cloned the TodoMVC
app. So, let’s go step by step. So, there’s index.html. I have to make almost no changes
here. The only change I need to do is add AngularFire and Firebase.js as dependencies.
That is not the right arrow, so let’s see. It’s in my clipboard history somewhere. So,
here I’ve added Firebase.js and AngularFire.js as dependencies. These are just as normal.
So, that’s all the changes we need to do to the index.html. Now, let’s go to app.js. Here,
we have TodoMVC is a new Angular module. I’m just going to add a single dependency. Right
now, it has none. I’m going to add Firebase as a dependency. Firebase is a module that’s
provided by AngularFire.js which we included earlier in indexfile.html. Now, in the to-do
controller, the TodoMVC app uses to-do storage, which is a wrapper over local storage to persistent
to-do items. We don’t need that. We’re going to replace or we’re going to add AngularFire
as a dependency, and we’re going to use AngularFire to persistent to-do items instead of–instead
of to-do storage. So, I’m just going to comment this line out here because we’re not using
to-do storage anymore. I’m going to say–FirebaseIO.com/todos. So, some URL, and then now I’m going to bind
the data that is that at this URL to scope out to-do’s which is what to-do storage was
doing. And the way I do that is I say AngularFire, URL, scope, todos. And then what happens is
AngularFire returns a promise because we have to go and fetch the data from a server that’s
asynchronous. You don’t want to be blocking on this. And Angular plays really well with
promises. So, you can just directly assign this to a scope variable and just have the
promise resolve itself. And you don’t have to worry it about it. What we do want to do
though is some of these functions over here like scope.addToDo. We don’t want people to
be adding to-do’s until the promise is resolved. So, what I’m going to do is I’m going to say
.then function and I’m just going to move everything inside the promise. I’m going to
go all the way to the end here, and that’s it. Now, the one part that we’re missing is
the old code was relying on the variable called to-do’s. The point is scope.todos, so we’re
just going to do that here. We’re going to say var todos=scope.todos. And scope.todos
is–will now point to a valid thing because we have associated that URL to scope.todos
via AngularFire. So, this line right here is what does that. So, inside the promise–after
the promise has been resolved, you can rely on scope.todos pointing to the latest data
that is available to Firebase. And we’re starting from scratch, it’s going to be empty but then
you add a to-do and then add to-do function, just modifies the scope variable, right? So,
it’s like saying scope.todos.push. So, there are no further changes required. You build
your Angular app just like you normally would have. So you would modify the models as when
you need to. And AngularFire will be watching for changes when–to the model, and when they
occur, they will be synchronized to the server. And then similarly, that server change will
trigger changes on models elsewhere. So, everywhere else where you’ve bound this URL to a particular
Angular model, right? So, that’s why this example is going to work. So, you can actually
join in the fun here. You can go to–let me see up here. Into firebase.github.io/angularfire/examples/todoMVC.
So, I’m going to open this–oh, someone’s already added a bunch. That is cool. All right.
So, I’m going to open this into–so those–none of those are my to-do’s, by the way. I have
a pretty crappy code. So, I’m going to pen two windows. So, this is Firefox and this
is Chrome. So, these could be–so, they don’t share a local storage, right? So, you can
expect to write a to-do in one place and have it appear on the other but the main point
being here is that this could be any of your browsers or this could be a browser halfway
across the world, it doesn’t matter. All the data is being persisted to Firebase, so everything
is going to be synchronized all the time. So, if I check an item here. You can see that
it almost instantly checks over there. Similarly, I do it the other way, someone unchecked it.
Thank you. And then if I delete items, they go one for two miles. New items appear instantly,
add more to-do’s. Thank you. So, as you can see, you can have literally thousands of people
working on this collaborative to-do list. Like all of you in here could be on this webpage
right now and everything works. So, when we release this demo, it was the world’s first
to-do based chat room. Because what happened was we had a bunch of people on this website
and they’re all chatting with each other using to-do items. So, that makes for an interesting
demo. All right, cool. So, it is scalable and it’s really easy. So, all you saw, we
took an existing Angular app that was persisting models to local storage and we added a couple
of lines of code to associate the models that already existed to a Firebase URL. And now
you can see that the app is now real time and it’s collaborative and can scale to many,
many, many users. So, that’s really what–all right. Let me see if I can get back to my
presentation. I think it’s here, yeah. Let me skip ahead. Yup, so that was a–just a
slightly more complex app other than synchronizing strings. You can synchronize JavaScript objects,
you can synchronize JavaScripts arrays, Boolean, strings. Anything that is an Angular module
can be synchronized with AngularFire. Now, on that to-do app, anyone could get on the
webpage and start adding items or removing items. There was no security because we opened
up the Firebase so that anyone could right to it or anyone could read to it. In the more
realistic scenario, you want to lockdown user data. So, you want to be sure that users can
only modify data that they should have access to. For example, if I sign up on a site, only
I should be able to modify my profile. Nobody else should be able to post comments as if
they were me. So, there’s–security and authentication are very, very important pieces for web apps.
And the way that you traditionally do them is by writing some server code that enforces
securities. So, you have a database on the backend and then you have some server code
that mediates access to the database by checking credentials via cookies or any other authentication
mechanisms that you might use. Just say, okay, are you user X? Then you’re only allowed to
write in this table over here. And this approach is traditionally really error prone because
then your security system is enforced as code. So, someone has to review the code to say,
are you checking for access at the right places and so forth. And also this approach is not
possible when all your apps is entirely fine inside as it is the case on our TODO app.
So in our TODO app, if we have to add some security, there’s like no way to do it other
than writing a server that mediates access to Firebase. So, authentication security has
traditionally have been a big problem with client-only apps. And so with Firebase, we
did a lot of thinking and I think we’ve kind of come up with something that’s really interesting.
And we’ve exposed that via AngularFire in a module called AngularFireAuth, servers called
AngularFireAuth. And I’m just going to go over it a little bit. The way they work is
you tie security to user authentication. So, the first step to implementing any sort of
real security is to identify who the user is. So, you want the user to have some kind
of log in process where they prove who they are. And the way we do that is using something
called JSON Web Tokens which are basically small sign snippets of JSON and they can kind
of provide proof of who a user is. If you don’t understand what JSON Web Tokens are,
don’t worry about it. If you are implementing a custom log in system then you will want
to know, but AngularFire provides easy wrappers on top of existing identity providers like
Facebook, GitHub, Persona, and Twitter to kind of wrap over all of these for you and
then generate the appropriate JSON Web Tokens. And so, were going to use one of these convenient
wrappers to end this demo that I’m going to show you right now. So, let’s look at the
code here. So, the important piece is you’re adding independency to AngularFireAuth in
your controller, and then, you’re calling AngularFireAuth. initialize with the URL to
the Firebase, a scope and then, a model, so, in this case, the model is user. So, what
this–what this does is it binds the user authentication stage to a Angular model called
scope.user. So, scope.user is going to be null when the user is not logged in, and scope.user
will be set to a JavaScript object that represents the logged in user when they are logged in.
And so, the side effect of that, is now I can rely on scope.user and use it in my mark
up here, so, I can say span ng-show=user, user.name and then, show a log out key. So,
this is when the user is logged in, show the username, and then, show a log out link. If
the user is not logged in so I can use ng-hide=user, link into a log in button. And then these
buttons called the log out and log in functions, and those are simply–they’re very simple,
they’re defying scope.login in is AngularFireAuth.login with Facebook with that string it could GitHub,
Twitter, any identity provider. Scope.logout is AngularFireAuth.logout. So, actually, let’s–before
we go into the security rules, let’s take a look at this in action. So, we have a little
demo app here, it’s called FireTube. Let me actually log out, so that–refresh. So, FireTube
is just a video commenting site. So, there’s a YouTube video and I want to be able to add
comments. Let’s define some characteristics for this app. I don’t want people to be able
to write comments if they’re not logged in, okay? So, I’m currently not logged in, I get
an alert that says, “You must be logged in to leave a comment.” How did this work? So,
let’s take a look at this code. So, this is FireTube.js that’s powering that webpage that
you just saw. You saw this already, AngularFireAuth.initialize with a URL scope and a user. In scope.addcomment
which is a function that’s called when the user tries to submit a comment, I say, if
not, $scope.user, “You must be logged in to leave a comment.” So, this is the code that’s
being triggered. Because scope.user was null because I’m not logged in, you can say, “Hey,
you need to be logged in to post a comment,” else, “I’ll add a comment”. So, let’s see
how the rest of it works. So, I’m going to log in. In this case, we’re going to log in
with Persona, so over here you’ll see scope.login is AngularFireAuth.login with Persona. So,
I’m going to click log in, I’m going to get a Persona pop-up, and I’m going to log in
with my e-mail. Now, when I do that, scope.user is going to be updated. So, over here, you
can see as soon as the log in succeeded, I can show my email address, and then, a log
out button. It’s just that easy. And then, now, if I try to submit the comment, it goes
through, because now I’m logged in and the comment shows up on–not just this client,
but also any other browser that you might visit. And if I try to add something here,
it’s not going to work because I’m not logged in. So, this is how you implement a simple
form of user authentication. The AngularFireAuth provides other useful utility methods. We
integrate with the angular route provider, so you can specify specific routes to be only
be accessible by users who are logged in just to kind of separate out of you–or about to
public–publicly accessible routes and routes that only makes sense for users that are logged
in. And some other features, you can go to the AngularFire GitHub and find out more details
about that, but we do more than just the log in, log out piece what you just–what you
just saw. Get back to the presentation. Here it is. Cool. So, now, you might be asking,
okay, so that seemed pretty silly to say if not, scope.user alert, you can’t log in. No,
that’s not real security, right? So, someone could always go into the web console and then
try to write data directly to Firebase using the–using the Firebase API. How does Firebase
know whether the user is logged in or not? So, the way that works is through the security
rules. So, on the server side, when you’re deploying your app, you have to tell the Firebase
or you cannot have to. So, Firebase is by default or open. Anyone can read or write
through it, but you can lock down access to a Firebase using declarative security rules.
So, this is the big difference that–between–see, between the way security is done in what apps
today, which is security is enforced by code, that is mediating access between your rest
front end and your database, but in Firebase, it’s more declarative. So, this means all
your security rules are in one place, can be easily audited by someone and they’re not
expressed in codes, so, there are lesser chances for bugs. So, what is a declarative security
rule means? It means that when the user logs in, remember we talked about JSON Web Tokens,
when a client provides a JSON Web Token to Firebase, we authenticate that user and verify
the signature on the JSON Web Token to verify that the user is really who they say they
are, and then we run the security rules every time someone’s trying to read or write data
to Firebase. So, read rule is executed at read time. So, in this case read is always
true which means anyone can always read data even if you’re not authenticated. But in this
particular example, in the write rule, I say, Auth.id==userid. So, let’s dig on that a little
bit. So, here, I have $userid which is just a variable. So, this means in my Firebase,
so, anant.firebaseio.com/foo. So, in this case, foo would be set to $userid, right?
And you can define this at any hierarchy point as you want because Firebase is a JSON store
where a hierarchy called data store, objects can have properties and properties can have
more properties, so, you can have a tree structure, and the security rules reflect the tree structure
off your data that you find in the store. So, in some ways if it look similar to a schema,
it’s a very loose schema about where data is going to fall in Firebase. So, if I say,
Auth.id==userid, it means that the person who’s currently trying to write data must
have the same ID as the location that they’re trying to write to. So, essentially, what
you’re saying is nobody can write to Anant.Firebase.–or Firebaseio.com/anant, other than Anant. Only
if I logged in as Anant can I write to that area. Does that make sense? So, that’s how
the declarative security rules work and we have more expressions that lets you do more
complex things and I encourage to look at an example called Firefeed which is essentially
a Twitter clone, but it’s built in–using entirely client side code. So, it’s a Twitter-like
app that you can post tweets to and respond, but it’s written only client side codes. There
is no server here that is enforcing security rules, like, if I post a direct a message
to you, that only you should able to read it and no one else, and someone who’s not
following me shouldn’t have my tweets appear in their timeline. There are many, many kinds
of security constraints on the data, and Firefeed has all of these security rules expressed
in under 60 lines of this kind of JSON that I would encourage you to look if you’re interested
more in the security aspects. But this is why the FireTube example works. Even though
we have enforced people not being able to post comments by doing the not scope.user
check, if you actually do try to write at the Firebase it’s going to fail because you’re
not logged in as the person who’s trying to post the comment. So, that’s how security–so,
you can have indoor and security without any server code with Firebase. That’s essentially
gist a bit. So, we already showed the demo and I think that’s the end of the presentation.
Yes. So, to summarize, AngularFireAuth help you synchronize your Angular models across
multiply clients, you can enforce security if needed without any server side code as
declarative–as declarative JSON rules. Finally, I hope that was clear and the AngularFireAuth
as well the AngularFire API itself is relatively new, something that we’ve put up in the last
month or so. And so, we–what we really love is your feedback on–please play with it and
give us your feedback on how it’s working. If you’re building a real-time app, that means
you kind of persist this data and have it updated in real time. Give AngularFire a try.
If you want user auth in your app, give AngularFireAuth a try and please, please, send us feedback
on what do you think of the API and how we can involve–evolve this in the future. You
can email me, [email protected], and that’s it.
>>Anant, can you take some questions?>>NARAYANAN: Yes, absolutely.
>>So, Ken and I have mics. Please come out to one aisle or the other to come ask your
question if you like.>>Hey.
>>NARAYANAN: Hey.>>Can you tell us something about the technology
behind Firebase, what’s actually going on behind the scenes?
>>NARAYANAN: Yeah, a little bit. So, we have some Firebase members in the back who might
be able to answer this better than I. But Firebase was written from scratch. It’s a
Scala server and we store all the data, like, in memory and then we have a custom protocol
that runs over WebSockets and we fall back the long-polling case WebSockets is not available.
So most of the time, it’s WebSockets on modern browsers, so we have this wire protocol that
goes over WebSockets that the client send a bunch of messages to the server and then
we process them and then broadcast it all clients that are currently listening for changes.
So, it’s just something that the Firebase team has been working on for the last year
and a half or so. I hope that answered your question. Okay.
>>So you actually answered all my questions.>>NARAYANAN: Okay.
>>Second question is, could you sort of differentiate between PubNub and–or Parse for example?
>>NARAYANAN: Sure. So, I’ll take those two separately. So, PubNub, I mentioned this earlier
in the talk, it’s primarily a message passing solution. So, you have to think in terms of
sending messages, receiving messages, and then you have to deal with problems of what
happens if the client is offline, how many messages do I buffer, how much history should
I keep. Firebase is a data synchronization platform. So that means that–so, one of the
realizations we came up with is most apps also need to persist data and not just pass
messages back and forth. So in the chat example, you want to send a chat to multiple people,
but you also want history of that chat being existent in the first place. So, by storing
data and then listing for changes to that data, you not only get the benefits of message
passing because by virtue of data changing, you’re getting a message, right? Then also
access to all the data that existed beforehand. So, I–so, we think that this is a better
way to approach the problem of, like, distributed data. So, that’s the big difference between
PubNub. With Parse, there’s a couple of differences. One is our security models are very different
as you saw. So we have this declarative security rule that lets you build client-only apps
without any server code at all and you don’t even have to write stuff, like Parse Cloud
Code lets you write some stuff that you need to execute on the Parse server, but this is
just declarative. It’s not imperative, so there’s no code that you need to write. You
just need to express security and Parse also is a–is a key value store kind of, so you
have objects that you persist, but Firebase is more a hierarchal JSON tree structure,
and it lends itself better to some certain kind of applications that better represent
data as a tree, because then you can access specific notes that you use–that you really
want to use without having to listen to everything and so forth. Yeah.
>>All right. So, Firebase is a service and that’s a great thing. By the way, I’ve been
using it and I’m playing with it. I enjoy it. But one of the things about having so
many services available all the time from all companies is that at some point it’s just
dependencies that’s going to cause issues. Is this open source, is it available just
in case unforeseen happens and all of a sudden [INDISTINCT]
>>NARAYANAN: So, a lot of our–a lot–a lot of code is open source, but the core Firebase
server itself is not. So, we have it–AngularFire itself is open source and we have–we have
a bunch of other libraries that are built on top of Firebase that are open source, but
the core Firebase server itself is currently not open source. We’re still figuring that
out. So dependency is a problem, but it’s kind of a symbiotic relationship. So, if people
don’t use Firebase because they’re afraid, then it is less likely that we stick around.
So it falls in the same bucket as like Amazon EC2, like people trusting cloud services is–we
have seen people move towards that trend because it is worth the benefit of you not having
to worry about running your own servers and stuff. So even if you were to open source
the Firebase, the server code itself, it may not be that useful because you still have
to worry about, like, setting it up on your servers, making sure that it scales well and
stuff, so then we would lose the whole as a service aspect of the service. So currently,
we have no plans, but that’s something that we’re definitely mindful of and we’ll see
if that changes in the future.>>A quick follow up.
>>NARAYANAN: Yup.>>Are like Android or iOS Libraries available?
>>NARAYANAN: Absolutely. So, we have an Android SPK as well as an iOS SPK.
>>Maybe over here. All right.>>As you mentioned that Firebase data is
persisted, can you export the data into…>>NARAYANAN: Yeah.
>>…a CSP format or…>>NARAYANAN: So, JSON–because all the data
stored in Firebase as JSON, you can very easily export it. So on Forge–I can actually just
show it to you guys. You have this big “Export JSON” button as well as “Import JSON” button.
So your data is yours. So even if Firebase isn’t there, like, your data is still there,
you can export it, you can save it, and then reuse it somewhere else if you need it. Yup.
>>This is regarding–I mean the URL that I’m calling in JavaScript. I mean, do you
provide any, kind of–I mean encoded URL like tokens kind of thing? Like, you know, if I
reach for Facebook, they’ll give me authentication tokens to–that I can use it in my application?
>>Yup, absolutely. So in the auth variable that you use in your security–in the security
rules that I showed, auth.ID will be sent to the Facebook ID. auth.name will be sent
to the Facebook username. And so you have access to all of that in the security rules.
With regards to URL over here, this is just anything that’s valid in a URL can be a valid
key. So in a JavaScript object, you can store whatever key name and that will reflect in
the URL here. Does that make sense or…>>Yes.
>>NARAYANAN: Okay.>>I have a question about something that
is a little bit technical detail.>>NARAYANAN: Uh-hmm.
>>I really like the idea that combined WebSockets plus the kind of MongoDB that’s kind of…
>>NARAYANAN: Uh-hmm.>>…a database. One question is about, when
some client updates the database, so they should send messages to the–to the–I mean,
the data base server and the–when the–and when the [INDISTINCT] starts, it also starts
listening on the messages.>>NARAYANAN: Uh-hmm.
>>So, when I update something as–should–will I still get a notice that the–notice that
that my data is being changed?>>NARAYANAN: Yes, absolutely. You will.
>>So in this case, it’s actually I’m updating the data. I’m still–I’m getting the notice
that the data is changes. Is it kind of redundant?>>NARAYANAN: No. So this is actually a very
important feature. So one of the things I didn’t mention is Firebase works great in
offline environments. And the reason that it works in offline environments is when you
make some change to a data, you’re going to get an event for that data change immediately
locally even if there’s no internet connection. And so this allows your app to be responsive
even when the user is in the tunnel. So, for example, in the FireTube example, if I post
a comment using AngularFire, right? So, you’re going to post a comment and the model is changed
immediately even though the message may not have made it to the server. And the result
of that is that the user’s comment is immediately visible in the DOM. So as far is the user
is concerned, the comment has been posted and then Firebase will automatically make
sure that the message reaches the next time the client is online and then that will propagate
to all of the other clients. So, this is actually important that we trigger the local changes–though
it may seem redundant, you know that you posted the comment…
>>Yeah.>>NARAYANAN:…but we want to fire the event
because we don’t want you to distinguish between local events and remote events.
>>Okay.>>NARAYANAN: All the events just happen on
the data. It doesn’t matter if it was triggered by your code or someone else’s code sitting
on a client somewhere else.>>Okay. Cool. Thanks.
>>NARAYANAN: All right.>>Actually I have a couple of questions.
The first one is, other than AngularFire, is there a way to write to the Firebase and
other API that I can write a process that updates the database? And is the notification
still work?>>NARAYANAN: Absolutely. So Firebase itself
has a bare bones JavaScript API that you can use without any frameworks like Backbone or
Angular. Though we do have bindings for Angular and Backbone mini front-end services, but
the code looks like this. So, if you go on the front page, click on the JavaScript API
documentation and you’ll get access to the raw JavaScript API that you can use to read
and write data. We also have a node.js library which you can write data from servers and
then we have an iOS SDK so that you can access that data from a native iOS app and an Android
SDK to access the same data from Android. And we try to keep the API as similar as possible
across all these services so that it’s easy for you guys to consume it.
>>And another question is about the security, you talked about authentication…
>>NARAYANAN: Yup.>>…and rules regarding identity. What about
group level access, are those supported in the rules?
>>NARAYANAN: Yes. So–because you can–so, I talked a little bit about JSON Web Tokens.
So, in the case you want to implement groups, you’ll have to generate your own tokens that
encodes the group information for a user. So, if I log in, your server knows which group
I belong to. So when you issue a JSON Web Token to the client, you include the group
information and the JSON Web Token and then in your security rules, you have access to
that via the auth variable. So you can say instead of auth.ID, you can say auth.group.
And then now you can refer to data that exist elsewhere in Firebase so you can have a root.child(‘groups’).
So if you have a /groups object on your Firebase that lists various groups, then you can do
root.child(‘groups’).hasChild(auth.group) which means that, “Oh, does the group that
exists in the token actually valid or not?” So, you can implement groups in that manner.
So, if you go to the Firebase documentation site and go to our security quick start, all
of this is detailed. Yeah.>>What kind of data manipulation can you
do with Firebase, like, queries or sorting?>>NARAYANAN: Yes, good question. So, data
in Firebase is sorted lexicographically by default. So, the key names, they’re sorted
alphabetically or lexicographically, I’m told is the correct term. And so we can generate
this automatically for you. So, if you call the .push function on a–on a Firebase reference,
it will automatically create chronologically incremental IDs. So, we’ll automatically do
that for you. That’s the most convenient thing that I would recommend. We also have a concept
called “Priorities” so you can attach priorities to individual nodes in Firebase, and then
we’ll sort them by priority if you need them. And then you can query stuff by priority by
some queries that we have here, so let me just show an example. So limit(), StartAt(),
and endAt () are three common queries. So, limit() says give me the only the last hundred
chat messages and because everything is sorted chronologically, you can just say .limit()
and then you can pass it to AngularFire. So, in AngularFire, you pass a URL. Instead of
passing URL, you can say new Firebase URL.limit(100), and that’ll only give the last hundred items
in the Angular model. So, we do have some queering, and so we’re looking to expand this
API. So right now, it’s good at doing windowing and pagination and giving recent items, but
it’s not so good at doing things like give me all the notes that contain content that
looks like this. Those kind of advanced queries are currently not possible directly although
you can structure a data in such a way that it’s made possible. And you can look at the
Firebase blog. There’s a blog post called denormalization of data and I will go into
details on how to do deeper queries like content-based queries. Yeah.
>>So–sorry for my voice. It sounds to me that the back end is sort of distributed at
eventually consistent system.>>NARAYANAN: Uh-hmm.
>>Is there guarantees that the event appear in the same order or that they actually even
appear on all of the clients or…>>NARAYANAN: Yes. So, that’s where the priority
is coming. So, events will always be fired in order of priority. And if a node doesn’t
have priority, they’re ordered in order of like lexicographical order. So, all the child
added events for example. If you’re using the Raw Firebase API, then they will be triggered.
If you’re using AngularFire, then the order in the Angular model of course is not applicable
to objects, JavaScript objects, but JavaScript arrays. The order will match what the order
was when the client added items to them, we do guarantee that.
>>Is there a chance that one client adds something to the database and another client
somewhere else adds something that the order gets kind of [INDISTINCT]
>>NARAYANAN: Yes. So, in those cases, we will trigger future events to correct the
order. So, for example in the internet disconnected case, if I add an item, I will trigger an
event for it immediately, but that–but that may not be correct because someone else may
have added an item at that position. So, next time when the client gets offline, we will
trigger further events to correct that order, so eventually, you will have the order that
is the canonical one on the server. Yeah.>>Thank you for the awesome presentation.
I have two questions. One is about the back end. You mentioned that it serializes everything
to everything JSON.>>NARAYANAN: Uh-hmm.
>>JSON doesn’t handle like cyclic references. Is there anything you do–you do about this?
>>NARAYANAN: It shouldn’t be possible for you to create cyclic references. So, we only
support JavaScript data that is serialisable. So, if JSON.parse and JSON.stringify will
show an error much before it gets to Firebase.>>Okay. That makes sense. The other question
is about the offline. You said that Firebase will work offline.
>>NARAYANAN: Uh-hmm.>>Does it actually persist itself from the
client so that I can just like reload my browser and next time I have internet connection,
things will just synchronize or…>>NARAYANAN: Not right now, though that–thought
that is coming very soon. We do want to do some kind of more diskPersistent. So, right
now, if you reload the page, you kind of lose the changes because the changes are kept in
memory, but diskPersistent is coming very soon.
>>Okay. And, sorry, one more question. Can you touch a little bit–can talk a little
bit about the conflict resolution?>>Uh-hmm.
>>With how that works?>>NARAYANAN: So in the standard case, you
mostly don’t have to worry about it because it is last stride wins and you usually don’t–usually
don’t structure such that all clients are writing to the same location all the time.
So you’re either attending to a list, or you’re modifying an area that is specific to that
client. In which case, chances of conflict are really low. In the case where you are
actually all writing to the same location in Firebase, and an example of this would
be a counter. We have a transaction perimeter, so you can do a transaction on a particular
location saying, “I want to increment the value at this location by 1:00.” And we–there’s
a .transaction function. You can look at up on the docs on the Firebase website. And that
will do it in such a way that there are no conflicts and only one client executes the
transaction at any given time.>>Sweet. So this is kind of more of implementation
question, but my company does [INDISTINCT] software, and so I don’t think I could use
Firebase structurally.>>NARAYANAN: Uh-hmm.
>>But I like the data model, which is sort of a hierarchical tree model where I can store
arbitrary, you know, small amounts of data in the leaf nodes, right? Did you guys look
into using, like, Apache ZooKeeper at all internally? Like, could I–could I–to make
a janky Firebase with ZooKeeper or something where I can–it’ll tell me when the leaf nodes
change and I can subscribe everything, and then…
>>NARAYANAN: It might–it might be possible. We haven’t tried it, but…
>>You said you’re using Scala, so I’m like, maybe there’s a ZooKeeper client involved
somewhere.>>NARAYANAN: So I don’t know. So there’s
Firebase–the people who actually wrote Firebase in the back, I did not have anything to do
with the variety of Firebase, but they might be able to answer your questions, so feel
free to go ahead and chat with them.>>I will go ahead. Thank you.
>>NARAYANAN: Yeah, yes.>>Hi. I have one question. Normally, we work–traditional
database and non-SQL database side by side, so do you have any advice or pattern which
both can work at the same time?>>NARAYANAN: With the SQL and…
>>For example, retrieving those user detail from one…
>>NARAYANAN: Yeah, absolutely. So there’s a blog post that I wrote just for you. You
should go to–you should go to Firebase blog and then look up the denormalization post
where I go in detail on taking an existing SQL schema and then mapping it to Firebase
and then–and then vice versa. So, definitely take a look at it. There’s a lot of details.
I don’t want to cover it because it could get lengthy, but definitely check it out.
It’s on the Firebase blog. You should be able to find it. Or just meet me after and we’ll
go in–yes. All right.>>How are you doing? Just a real quick question.
Are there any older browser quirks we have to be aware of or anything like that?
>>NARAYANAN: Nope. So the good news is Firebase takes care of all of that for you, so we went
into painstaking detail trying to run our code on multiple different browsers and we’ve
tried to accommodate for all of them. And that’s one of the advantages of using a service
like Firebase is that, as new browser cores come up, like, it is our responsibility to
keep up to date to them and make sure the library keeps working as new standards come
up and new quirks appear. Thankfully, you don’t have to worry about any of that. Yes.
>>Oh, I have a–I have a question about those applications.
>>NARAYANAN: Uh-hmm.>>And you said that just model change, it
all changes going to Firebase. What about if we need some validation before changes
has been applied to Firebase?>>NARAYANAN: Absolutely.
>>How it should be done.>>NARAYANAN: That is actually a great question.
So, there’s one API that I didn’t cover in AngularFire. It’s called an AngularFire Collection,
and AngularFire Collection is another service provided by AngularFire.js, which is a more
explicit API, so AngularFire automatically synchronizes a model to the server. But with
AngularFire Collection, you have to explicitly call a .add or.remove function to make changes
on the server. So you can listen for changes to models normally using $scope.$watch or
something. Do some preprocessing or validation, and then call AngularFireCollection.add on
that object if you–to explicitly put the data on Firebase. So just go to the AngularFire
to get help and look for AngularFire Collection and there’s documentation on how to use it.
Yeah.>>Do you support transactions?
>>NARAYANAN: Yes. So you can go to the documentation here and go to transactions. So here’s an
example of transaction of how to do an increment. So a transaction is essentially a function
that takes the current value and then returns a new value based on the current value. In
this case, it’s a simple counter. That’s how it works.
>>And you can do across different?>>NARAYANAN: This is across many, many clients,
yes, exactly, yes.>>So a slightly different question. In the–you
mentioned about, normally, your data structure is a simple root, but your pricing is based
on data storage, so I’m–I take it that an application can have multiple roots.
>>NARAYANAN: Yes.>>Okay.
>>NARAYANAN: It can.>>So it’s up to you to structure…
>>NARAYANAN: You can structure it–yes, exactly.>>Another one, sorry. Archiving.
>>NARAYANAN: Uh-huh.>>Do you guys do archiving?
>>NARAYANAN: We don’t, but we can export your data as JSON any time using a REST API.
So, you can manually implement archiving by having a server process get all your data
and then store it as JSON snapshots now and then.
>>No. I was thinking more, I guess, in this case, an application has to take care of–if,
let’s say, I want to make sure that all rights are stored.
>>NARAYANAN: Uh-hmm.>>Then I have to have it in the application
so you have a timestamp.>>NARAYANAN: That’s right, exactly. Yes.
That’s how you’d have to do it. Yes, cool.>>I have a question regarding the authentication.
>>NARAYANAN: Uh-hmm.>>So you told that you have–you can define
the rules on read and write, whatever you have shown, that main structure.
>>NARAYANAN: Yup.>>So, but those read and write rules, I need
to define the Firebase [INDISTINCT] right?>>NARAYANAN: Exactly, yes.
>>So I can define my own rules.>>NARAYANAN: You can define your own rules
using the language that we have to–and it’s a JavaScript-like language. It’s not all of
JavaScript but some of it, and there are some predefined variables available to you, like
the auth variable, and there’s the root variable, and then the data variable, which is the first
data at that location, the new data variable which refers to the incoming data. So you
have access to all these predefined JavaScript variables, and you write these expressions
that use that data in different ways, and returns a boolean value that says whether
or not to allow the read or write.>>The rules are also the set of–you know,
you have some sets, or 21 or 20 by some numbers which you are required based on the [INDISTINCT]
>>NARAYANAN: Exactly.>>There’s not, like, I can define my own
rule, and then, you know, I can put that rule…>>NARAYANAN: No, you can define your own
rule but you have to construct the rules using those language. So think of it as a subset
of JavaScript that you can execute at the time the data is trying to be written or read.
It’s a subset of JavaScript.>>Okay. And one more question. So, what are
the data exist in the Firebase? Can I export and put in the–can I, you know–immediately
the data goes Firebase, I won’t replicate the data in other…
>>NARAYANAN: Yup, yup, so all the data is accessible as just JSON snapshots and we have
the REST API that you can grab and take the JSON and put it anywhere you want.
>>Okay. So how big, you know–you know, how much data we can store in Firebase?
>>NARAYANAN: You can store up to…>>We can have any kind of this thing?
>>NARAYANAN: Yeah, you can store up to 10 megabytes of data at every leaf node.
>>How much you will charge, you know, data scalable?
>>NARAYANAN: So, there’s a pricing page on our website that you should take a look at.
So we have different caps for different tiers of storage, how much of the storage you want
to use. So, you know, hundred megabytes is free and something like that.
>>Thank you.>>Quick question about security. Is there
a support for non-repudiation? Like, to know, who did what update and when…
>>NARAYANAN: I’m sorry, repeat? Could you repeat that?
>>Security question. Support for non-repudiation, is there a way to know who did the transaction
and at what time, like, who did an update?>>NARAYANAN: Not directly but you can implement
such a system using security rules. So you can enforce people to write the time stamp
at which they did a certain operation, and store that itself in Firebase. And you can
enforce that using the security rules to make sure everyone who tries to do something also
adds an entry in the log or something like that.
>>Right, and that’s entirely based on the file that you put on the server so nothing…
>>NARAYANAN: That’s right, it’s the JSON file, exactly, and you do a deployment time
when you deploy your app and no one else has access to it, obviously, that’s…
>>Yeah.>>NARAYANAN: why you do security.
>>Okay. Thanks.>>Yeah, my question is, again, onto the security.
I saw that simple log in kind of a thing that you could use Facebook and LinkedIn or whatever
the–what…>>NARAYANAN: Uh-huh.
>>…but JSON Web Token as you mentioned about, are they pertaining to the Firebase’s
domain or are those tokens available if I have my own pack?
>>NARAYANAN: No, so the tokens are generated using a secret that is available only to you.
So, if I–if you go into your Forge or your Firebase, and then go to the Auth tab, there’s
secrets here that you can generate, and we always generate one for you. So you take the
secret and then you generate a token using the secret and we make that easy. If you go
to firebase.com, and then go to custom log in, we have links to token generators for
multiple languages, so .NET, Java and oJSP [INDISTINCT] so you can provide these libraries
with the–with the secret that you have in your Forge, and they will generate tokens
for you with arbitrary payload.>>My question is actually a little vague.
I mean, I use this–your simple–to authenticate…>>NARAYANAN: Uh-hmm.
>>…but I want to access some other resource on my own back end server…
>>NARAYANAN: Uh-hmm.>>…and I want to know who actually is logged
in right now.>>NARAYANAN: Uh-huh.
>>So it possible?>>NARAYANAN: Yes.
>>Okay.>>NARAYANAN: Yes, yeah.
>>So then I can send the token which is generated by your API?
>>NARAYANAN: That’s right, exactly, absolutely, yeah. So, simple log in will generate the
same JWT’s that you would generate if you had generated them on your server. It’s the
same, yeah.>>Now, for my project, I use MongoDB, and
I think that the only reason I would like to use Firebase because there’s a phase of
that project that actually–will be–will be very nice, like, Google Docs that many
people can write that kind of document [INDISTINCT] their document, or just some stuff in–just
for multitask.>>NARAYANAN: Uh-hmm.
>>And I’m just thinking about if there are some of resource, some tutorials, something
in the website that teach how–for example, like, I don’t know about the JS, I can–after–I
don’t know–save that document…>>NARAYANAN: Yup.
>>…take the data from Firebase and bring home…
>>NARAYANAN: Yup.>>…a MongoDB database?
>>NARAYANAN: So luckily, you don’t have to do too much work. So, firepad.io is already
a collaborative document, which that you can embed, and it uses Firebase to persist the
data of the document and all changes, it takes care of all the collaborative editing, so
it uses the technique called OT, Operational Transform. We take care of all those details.
There’s also an export feature that’s coming soon to Firepad. So, go to firepad.io and
check it out. It’s super easy to use.>>Okay, but how is [INDISTINCT]
>>NARAYANAN: So, if you go to the GitHub source code, there’s a source code on how–on
the entire implementation, how to use this Firebase and everything, so give it a–yeah,
give it a look. It’s open source, so, yeah.>>Right, I really like AngularJS and I’ve
been working with MongoDB a lot as well, and one of the things I really like about it is
this built-in special analysis.>>NARAYANAN: Uh-hmm.
>>I just want to know if there was something like that.
>>NARAYANAN: Not currently, so, the kind of queries you can do with Firebase are ones
that you know of beforehand. If you want to do queries based on content that you didn’t
know or you didn’t know what kind of query the user is going to do, you can’t currently
do that without denormalizing your data and, like, creating a schema in such a way that
you are able to do those queries. We are considering how we can do that. The reason we haven’t
added them yet is, because Firebase is a real-time data store, we don’t want to provide any kind
of queries that we can’t guarantee to be real-time. So, for example, some of the Mongo queries
could take forever, depending on the type of query and the size of data that you have.
And that’s why we don’t expose those kinds of queries that we can’t guarantee will be
fast. So, we’re slowly but surely, adding all kinds of queries that we can guarantee
to be fast. There are some classes that we can do it, and we’d love to chat more about
what you’re specific used cases and see if we can accommodate that.
>>Thank you.>>NARAYANAN: Thanks so much.
>>Absolutely.>>NARAYANAN: Thanks everyone for coming again.

Danny Hutson

8 thoughts on “Realtime Web Apps with AngularJS and Firebase

  1. An year passed and i didn't hear about this! what a real shame, i was trying to keep my head in the sand and use PHP for life!

Leave a Reply

Your email address will not be published. Required fields are marked *