DAVID EAST: Hey, everybody.
Welcome back.
[BEEP]
Welcome to the--
[BEEP]
SPEAKER 1: Still rolling.
DAVID EAST: Still rolling.
[BEEP]
And we're back.
[MUSIC PLAYING]
Hey, everybody.
Welcome to the fifth lesson in the Firebase Database
for SQL Developers series.
And in this lesson, we're going to be talking all about joins.
So the Firebase database SDK doesn't have any methods
for joining data specifically.
But that doesn't mean that you can't take data
from one location and then find the related data
and merge into one set.
So to see how we would do that, let's dive right down
into the laptop.
This is a database of events.
We have events, users, and attendees.
And an attendee is obviously a user that goes to an event.
And if we want to get back all of the attendee's data,
we would have to write this SQL query right here.
So we have two inner join statements.
And we are inner-joining events with attendees and attendees
with users.
And we can do this because of the foreign keys
in the Attendees table.
So Attendees has EventId, which references events.
And it also has a user ID, which references users.
So when we inner join these together,
we can then create the data set we need to get all
the users' data that are going to a specific event.
So how would we do this in the Firebase database?
The Firebase database, the data is structured as JSON.
And our top-level keys are users, events,
and eventAttendees.
And eventAttendees is how we show which users
are going to which events.
So the fm key is the same key as the events key.
So we know that all of the users underneath fm and events keys
are the same users that are going to the event, which
is the key of fm.
So how would we do the join in this case?
Well, we would use the real-time database SDK,
and we would get a reference to the event attendees at the fm
key.
And then we would start doing a child_added event.
And this would fire back each user
that is going to the event.
So the first time, we would get a key of 1,
which is David, and then a key of 9, which is Alice.
And that just gives us the name and not all the other user
data.
So to get all the other user data,
we then have to do a join.
So what we would first start out by doing is
is we'd create a reference to that user's location
inside of the callback.
So we can create a user reference
using the Snapshots key.
Because the way we structure the data is that the Snapshots
key is the UID for that user.
And then once we have created this reference,
we can just do the Once method, specify the value event,
and then return the user in the promise.
And this gives us back our specific user data
for all the users that are going to this event.
Now, one thing you might want to note
is that we're using the Once method.
And this will only retrieve that data one time
and not listen in real time.
And this is the easiest way to do a join,
because you're not going to have to worry
about inner subscriptions.
And to see what those are, let's see what happens
when we use the On method.
So using On value, this will listen to updates
for the user in real time.
But when you use an On method, you always
need to be able to dispose of that.
So if you no longer need to listen
to these updates in real time, you
can call Ref.off with the handle.
And then that way, you aren't listening to that user anymore.
So when you listen to an event in real time,
you are going to need to be able to dispose of that event.
And so you can use the Off method to stop listening,
but you also have to pass in a handle.
And when you listen using the On method,
a handle is returned to you.
So inside of each child-added callback,
we're creating a new real-time listener.
And so this is a new handle that we
have to keep track of for each attendee.
So this is how you would keep track of each handle,
so we could actually unsubscribe from the real-time events.
So we'll create an array of handles.
And then inside of the child_added callback,
we'll do our join, where we grab the user reference
and then get back the user data.
And then after that, we will push the handle
onto the handles array.
And then somewhere later down the line
when you need to dispose of all the child events,
you can just loop through the array,
and then you can call the Off method with the handle.
So that is for your more complex situations,
where you need to keep both data sets updated together
in real time.
But as you can see, for most of the time,
when you are grabbing reference data, like the user data,
it might not always be changing in real time.
So you can just get away with using Once rather
than having to keep track of all the handles with the On method.
So now that we've taken a look at this,
let's go dive in and write some code.
So right here I have a JS Bin with a few variables
at the top.
We have an eventKey, which is a key to just one event; a root
reference to our database; an attendees reference;
and the users reference.
So let's first see all of the attendees at this event.
So to do that, I'll just say attendeesRef.once, value.
And we can log the snapshot.
So console.log.
Snap that val.
And we want to make sure we use the specific event.
So I'll say child of eventKey.
So now we'll run it.
And these are all of the attendees at this event.
And you can see that we have this key right here and then
the user's name.
So Margaret right here.
And this key is actually Margaret's UID.
And it's the same here for Anthony.
So all of these keys are the unique identifiers
underneath the user's key.
So since we have this key, we can know how to join the data.
So I'll write a function, and we'll call it getUsersAtEvent.
We'll pass in a key and a callback.
And so now we could say attendeesRef.child of key.
Then we could say on, child_added,
and pass through a snapshot.
So child_added will fire off for every user.
So this came back as an entire object in the console,
because we did a Once value.
But on child_added, it's going to fire off line by line.
So since we know that the key of the snapshot
will be the user's ID, we can actually create a reference
to that user's location.
So we'll create a userRef, and that
is usersRef.child of snap.key.
And then now we can say userRef.once, value.
Get that user's data as a snapshot.
And then rather than actually writing this function right
here, we can just provide our callback
since will be called with the snapshot.
So now we can call this method.
And so we'll say getUsersAtEvent.
We'll pass through our event key.
And then a callback function, which we'll just
log the value to the console.
So now I'll clear this out.
We'll run.
And you can see that we have all of the entire data
sets for each user that is going to the event.
So that's how you do joins in the Firebase database.
And you can see that it's really dependent on how
you set up your data structure.
And when you share keys across your data structure,
it makes it really easy to find any related data using
that key.
So that's all for this time.
If you like this video, make sure to like and subscribe.
And stay tuned to the next lesson where
we're going to talk about denormalization, which
is a cornerstone in structuring your data for NoSQL databases.
So that's all, and I will see you all in the next lesson.
Thanks for watching our video.
You might also want to check out this video or even this one.
I really like that one.
And make sure to subscribe.
And then now you could just watch me try
to catch popcorn in my mouth.
[BEEP]
Oh, two in a row.