Firebase Realtime Database — Polycasts #58


[MUSIC PLAYING] ROB DODSON: Hey, everybody. What’s up? It’s Rob Dodson. Welcome back to the show. So in the last episode,
I was showing you how you set up Firebase
authentication in your Polymer project. Today, I want to
continue on from where we left off in the
last episode and start working with Firebase’s
real-time database. And so what we’re
going to build today is going to be kind of like
a simple note-taking app, or like a to-do
list sort of thing. So follow me over
here on my laptop. I’m already signed into
the Firebase console. And because I want to have
each user have their own space in the database for
their own unique notes, I’m going to need to
set up some database rules about who can write to
which parts of the database. So if I go to the
Database section here– I click on the Database
tab– if you just set up your project, you’ll
probably see a note right here that says, like,
“Default security rules require users to
be authenticated,” and then there’s this
Learn More button. And you can click on that. And actually, it’ll
open up a new tab, and it’ll explain how
Firebase’s database rules work. Firebase’s database rules use
sort of a JSON-like syntax, which is very interesting. But the thing
that’s really handy here is the Sample
Rules section. So like I said, I want
to have every user have their own unique
space in the database, and that’s such a common
ask that there’s already, if you click on
this User tab here, there’s already
some example rules that will do that for you. And so I can walk
through how these work. So basically, we’ve had our
rules object, and then we’re going to define it so
it matches the URLs that we’ll use for
our database calls. So we’re going to start
with a users object right at the root of our database. And then within that, there’s
this sort of special syntax here for this $uid thing. And that is kind of
like a Firebase database variable of sorts. It’s a dynamic rule. And what that will do is refer
to whatever is the current user ID that we are working with–
sort of the /users/ some user ID. And then we’re
saying whoever can read to that space, their
uid or the uid space that we’re trying to write
to– that will need to match the authenticated user’s uid. So that’s for reading
and for writing. So I’m just going to copy
this bit of boilerplate here, go back to my console,
and click on the Rules tab. And I can highlight all
this, paste that in there, and then make sure
to click Publish so that these rules become active. Cool. We’ve said that
only certain users can write to certain
spots in the database. Basically, you
can’t read and write to other people’s to-do list. So far, so good? Now, follow me back over to
my laptop, and let’s go ahead and start putting some
data in the database. So I’m going to create a new
element called my-notes.html, and I’m just going to paste
in some HTML imports that I’ve saved. And I’ll close the sidebar there
so we can bump this up a little bit and you can
see what I’ve got. So in this element,
I’m importing Polymer, I’m importing firebase-auth. So I’ll show you why
we need that again. I’m importing firebase-query. So this is what we’ll use
to actually talk to and read from the database. Paper-input– so the user can
enter some values, and then iron-flex-layout. And I think we’ve actually
maybe already imported paper-buttons somewhere
else, but it’s probably good to import that here, as
well, because we’re going to use a paper-button, too. So I’ll say paper-button. Rad. Let us begin by
defining an element. So we’re just going to
call this element my-notes. And the first thing
I’m going to do is actually use the
firebase-auth element, again, inside of my-notes. Now, I used this in
our previous episode to build our sign-in
and sign-out buttons. So here, what I’m
to do is I’m also going to expose the user
object inside of this element. And what’s kind of cool about
the firebase-auth element is that whenever a user
signs in, basically, all instances of the
firebase-auth element that we have sprinkled
in our app– all of them will simultaneously
get that new user data. They’ll get the user object. And so you can treat
this element like a model that any other element can
just sort of declaratively bind to and extract information
about the user. So you can pop these auth
elements into different spots in your app, wherever
you might need to reference the user for
some reason, which is pretty interesting and pretty handy. So we’re going to
combine that with the firebase-query element. So the firebase-query
element basically lets us talk to the
Firebase database, and specifically, talk to
arrays in the Firebase database. So I’m going to give this
element an ID of query. So we’ll say ID is query. We will use that later to
reference it in our JavaScript. We’re going to say
that it’s path. So this is the path in the
database where we’re going to be reading and writing to. That will be /users/, and then
we will bind to the current user’s user ID, and then we will
write to their notes section. And then we’ll say the data
that comes back from Firebase– we’re going to expose that in
our app as this notes object. So I’ll go down here to
my element definition. I will define a properties
object for that notes thing. So we’ll say the type is object. And now I want to add
sort of like a list so I can render out all of those
to-dos that start coming back from the server. So let’s see. So we’ll start. We’ll define a div. We’ll just call it card
or something like that. And then inside of here,
I’m going to create maybe another div called notes. [INAUDIBLE] say notes. Inside of here,
make a ul, and we’ll give it an ID of notes-list. Instead of here, I’m going
to do a dom-repeat template. So I’ll say template
is dom-repeat. The items that it’s
going to iterate over will be those notes that
are coming in from the user. And we will say that
we want each note to be referred to just as a note. And then inside of here,
we’ll create list items. And inside of each
list item, I will just drop in a paragraph tag. I’ll give it a class of
content, and I will say that I want the note.content. So we haven’t really defined
what a note looks like, but I’m going to assume
that it’ll have this content property on it, and that’ll just
be the text content of the note itself. The next thing I
need to do is I need to add some controls so someone
can type in a note, and then a button so that they can
add it and it’ll send it up to Firebase. So I’ve actually got
a little bit of code for this that I’ve just
already saved in my clipboard. So I’ll just paste that
in here real quick, and we can walk through this. So I’ve got a paper-input
element with an ID of input. That’ll be useful
later because we’ll refer to it in JavaScript. And it’s just got a label
that tells the person, “Hey, take a note.” And then I’ve got inside of that
a paper-button with an ID of add. We’re going to refer to
this in JavaScript, too. And basically, whenever
someone taps on it, we’re just going to
run this add function. So let’s implement
that add function. So right under our properties,
we’ll say add is function. And so what we want
to do is we want to take the reference to
the Firebase database, and there’s two things
you can do then. You can either set a value,
or you can push values. Setting is if you’re just
dropping in a single object. Pushing is if you’re
pushing array-like data up to the database, and
that’s basically what we’re doing with these to-dos. So we want to use
the push method on our Firebase instance. So to do that, we’re
going to go up here. We’ll look at our query element,
which has this ID of query, and we can say this.$.query.ref. So that’s going to be a
reference to that path that it has defined– so
/users, user ID, notes. So give me a reference to
that path in the database, and then push an object to it. And this object is just going
to have one property, which will be content. And then that’s going to come
from this .$.input.value. So that’s just our
input textfield. And after someone
hits the Add button, it’d be nice to clear
out the text field so it can keep adding to-dos. So right after we
push the value, we’ll also say
this.$.input.value equals no. Let’s switch over to our
terminal and fire this up. So we’ll say firebase serve,
and then go to localhost 5000. We will open up our
console because errors happen sometimes. We will go, and we will
start typing a note. So let’s see. We’ll say, “Hello
Polycasters,” and we’ll add it. And there we go. Now it’s showing up
inside of our list. So that just sort of confirms
that everything worked. We could, if we want, though,
go over to the Firebase console, go back to the Data
tab, and you can see these green rectangles
indicate that we just wrote some data to the database. So you can see users,
my crazy user ID, notes, and then this unique ID. So every time you push
something to Firebase– any time you’re working
with array-like data– instead of using numeric
indices like 0, 1, 2, Firebase will actually
create unique IDs. And this is really
useful because if you have a bunch of different
people all trying to push to the database
at the same time, if you were using just
numeric keys like 0, 1, 2, you could probably end up
with some weird transactional issues. So instead, Firebase
creates these sort of unique identifiers. So it can do the
bookkeeping after the fact to make sure data gets
synchronized and mushed together in the right ordering. And I can see inside of here the
actual value content, “Hello, Polycasters.” What’s cool about the
Firebase database– this is probably my absolute
favorite feature of Firebase– is it’s super easy to
play around with the data once it’s in there. So for instance, if I want to
change this to finish the demo, I can just update the text–
so “Finish this demo”– and hit Enter. And now everything turns yellow
to indicate that it changed. I go back to my
note-taking app, and you can see that that value has
been updated here, as well. So we can add some more to-dos. We could say, “Go out and vote.” It is November 8 as
I’m recording this. And then we will say,
“Hopefully celebrate??” So we can keep adding things
to this to-do list if we want. The next thing I
want to do, though, is I want to be able to delete
items off of my to-do list. And this is pretty
easy to do, as well. So we go back to
our code editor, and I’m going to add a
couple more imports up here to the top. So I’m going to drop in. Let’s see. I’ve got a couple
of these saved. So I’ll drop in a
paper-input button, and I’m also going to
drop in iron-icons. Now, I’m only going to use one
icon from the iron-icons set. And so normally, I
would say if you’re using only a handful of icons
from the iron-icons set, it’s best to go and
create your own icon set. And you can do that pretty
easily using iron-iconset-svg, and literally just copy
and pasting the stuff out of iron-icons. But because we’re
just doing a demo, I’m not going to go through
making my entire icon set. So I’m going to use
iron-icons directly. But for performance
overhead, it’s often a good idea just to
create your own icon set. So I’m going to include
a paper-icon-button. And then basically
right after where we’ve written the
content for our note, I’m just going to drop
in a paper-icon-button. I’m giving it an icon of
clear so it’ll be like an x. And then I’ve got this
property here called note, and I’m actually just
setting a property on the paper-icon-button. I’m setting a reference
to the entire note object that this line item
is referring to. And the reason I’m doing
that is because I’m going to use the
key of that note to then go on and
delete it in Firebase. And so lastly, I’ve got this
on-tap event listener here, and I’m saying I want to
call this remove function. So let’s implement
that remove function. So I’m going to say remove is
a function– gets an event. So we’ll say that
the key is equal to e.CurrentTarget.note.key. And I think maybe they use $key
to reference it in Firebase. Note.key– I think that’s right. Yep. And then we’re going to
say this.$.query.child, and then we will
give it the key. We’re giving it this value right
here– this.child.key.remove. So that basically says
go to the database, find the object that
matches this key, delete it. So go back to [INAUDIBLE]. Actually, before I do that,
I’m going to drop in some CSS, as well, to make this
look really pretty. So right above our
Firebase off, we’ll drop in a big style block. And honestly, you don’t
really need to worry too much about what I’m doing here. I’m just sort of
positioning things so our icon’s
floating to the right and our text is
to the left using iron-flex-layout–
nothing too interesting. So I’m not going to spend
too much time on it. But I just wanted the
demo to look nice. I’d go back to [INAUDIBLE]–
refresh the page. And now we have our
notes showing up here. We’ve got these Xs
showing up here, and I can go and X them out. And who, we got an error. This.$.query.child
remove is not a function. What? Let’s see what I
typed wrong here. I need to have ref.child. Let’s try that again. Refresh the page, and we will–
boom– start deleting items. Yeah, yeah. And we win. We’re all done, I think. So that about
covers it for today. We covered some of
the basics of working with the real-time database. We’ve got user authentication
working with this app. The next episode, I think
I want to explore maybe how we deploy this thing and
get it working on Firebase hosting– might try to come
up with some other interesting topics to include in
that episode, as well. If there’s anything that maybe
you’re interested in seeing, please leave me a
comment down below and I can try and work that
in, or you can hit me up on a social network of your
choosing at #AskPolymer. As always, thank you
so much for watching, and I’ll see you next time. [MUSIC PLAYING] Hey, what’s up? Thank you so much for watching
this episode of “Polycast.” If you want to check out
more, I got some over here on the playlist. And you can also always
click the Subscribe button and get notified when
we launch new episodes. Thanks for watching.

Danny Hutson

Leave a Reply

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