Securing your data structure with Security Rules – The Firebase Database For SQL Developers #8

Securing your data structure with Security Rules – The Firebase Database For SQL Developers #8


[BEEPING] DAVID EAST: I don’t even think
I clipped on the last one. Maybe. I don’t know. Let’s make this one count. Hey, everyone. Welcome to the eighth lesson
in the Firebase Database for SQL Developers series. And today, we’re going to learn
all about protecting your data structure with security rules. So let’s dive right down
into the laptop and begin. To insert data into
a SQL database, you first need to
create a table. And this table
must have a schema. And a schema is made up of
a column and then a series of constraints. So this column of ID has
a not null constraint, and we’re also constraining
the data type to be an integer. So we can also
specify other columns, and they can also
have constraints. And we must provide a
primary key constraint, which is the unique identifier
for every record in this table. The Firebase database
doesn’t have tables, and it doesn’t have schemas. Instead of tables
with rows and columns, it has JSON with
keys and values. So at the root, we can
create a key of users, and then below, we
can create child keys that have values for our users. So we can insert
whatever we want. So that means for
this user, we can create properties of name,
bio, and profile image, and then we can
insert another user that has name, bio, profile
image, and favorite color. And you also notice that
profile image, in this case, is actually a number. And there’s nothing that
stops us from doing this. And also, there’s nothing
that stops someone from just deleting
your data unless you specify security rules. So there’s three
things to learn when you’re starting
with security rules, and the first is
paths and rules. Security rules are
written in a JSON file, and this is totally
separate from the database. And every security rules
file starts with a rules key. And then below there,
we can map our rules to our data structure
in the database. So since we have a path
of users in the database, we’ll create a path of
users in our security rules. And then once we have our
paths, we can specify our rules. And there are three
rules you can use. There is read,
which determines who can read the data at this path. There is write, which
determines who can write data to this path, and
lastly validate, which determines what the data
structure is at this path. And all of these rules must
evaluate out to an expression. So it’s either true or false. If it’s true, the write to
the database or the read will be accepted. But if it’s false,
it will be rejected. So right now, this is
not really a useful rule. We’re essentially saying that
anyone can read or write data at users, and we can use any
data structure that we like. And also, what’s not very useful
is that we’re not actually writing rules for
any child users. We’re writing a rule for
specifically the user’s key. So we want to be able
to dynamically apply these rules to any child users. And to do that, we
can use wildcards. So right now, we’re
only applying this rule to the users key. But if we specify
a wildcard, which starts with a dollar
sign, we’re essentially creating a variable. And we’re saying that this
rule applies to any children underneath the users key. And we can specify what the key
is with the dollar wildcard. And in this case, we’re
calling it dollar UID. But since it’s a
variable, you can really call it whatever you want. And dollar UID will
hold the child key value that we’re trying to access. So if you’re trying
to access /user/1, dollar UID will represent 1. But if you try to
access /user/2, dollar UID will
hold the value of 2. And we can see how this
actually looks like in code. So if we create a root reference
to the database and then nest down to users, and then we
can create a variable of UID. And then from this variable,
we can create a reference to a specific user. And this is exactly what
the dollar UID wildcard is doing in our security rules. So now that we have
the ability to write this rule for any
child, we actually want to do something useful
rather than just say true for all of our rules. And to write a
useful expression, we need to use server variables. There are six server variables
that the Firebase database provides you with. There is auth, which is the
currently authenticated user. There is data, which is the
data that exists at that path. There is new data, which is the
newly-posted data at that path. And this is only available
in .write and .validate, because those are the only times
we’ll actually have new data being posted. There is now, which
is a server time stamp of the current time on
the server, and root, which will bring you to the
root of your database, and also the dollar
wild cards, which we created with dollar UID. So now that we have access
to these server variables, we can write useful rules. For .read and .write, we can
create rules that say only users can access their own data. By saying auth.uid is equal
to the dollar UID wildcard, we’re essentially saying that
if the currently-authenticated user’s UID is equal to the UID
that we’re trying to access, that person can
read or write data. So if it’s /users/1 and the
currently authenticated user has the ID of 1, we can
allow that read or write. But if the currently
authenticated user is 2 and we’re trying to access
/users/1, that will fail, because 1 is not equal to 2. And with validate, we’re looking
at the newly-posted data, and we’re just checking
to see that it exists, that no one is posting null. But we actually can use other
methods to check the data. By calling .child on new data,
we can pass in a string and see if a child property exists. And we can even
check its data type by calling the is string method. And there’s also other
methods for other data types. And since this is
just an expression, we can actually tack
on other conditions. So in this case, we
can check for the bio and see if it’s a
string, and then we can even check the
bio string length and make sure that
it’s less than 500, and then also check
the profile image and ensure that it’s a string. Previously when we tried
to add the user of Alice, we were able to, even though
profile image was a number. But now with these security
rules applied, this would fail. So if we went and changed the
profile image from a number to a string, it would pass. Another thing that you
can do with security rules is you can create foreign
key like constructs. So in our database, we
have our list of users, and we can have a
property called location. And this is where
the user lives. So David lives in SF. And we can also
provide a lookup, which contains all of
the valid locations that we support in the database. And if we want to make
sure that we are only adding valid locations, we
can write a validate rule that takes us to the roots, then
goes to the child of location. So now we have access to
all of the locations that exist in the database. And then from there, we can go
into the newly-posted data set and call that child of
location to get back the new location
that’s attempting to be added to the database. We can get its value, and then
after that, we can call exists. And what this will do
is it will make sure that the newly-added location
exists in the database. And if it doesn’t, the
write will be rejected. So securing and protecting
your data structure is really important. So you probably want to be able
to test out that what you’re doing is actually working. And to do that, you
can use the simulator. So right here, we have a
Firebase database opened up in the Firebase console. And you can see that
we’re using similar data structures that we’ve
created in this series. We have our users
data structure. And you can see that we’re
storing a user named Margaret that lives in San Francisco. And then we also have
a locations lookup for all the valid
locations we can accept. So now if we tap over
to the Rules tab, we can write some
security rules. And you can see to the left that
we have this Simulator panel. And if this isn’t
already opened up, you can just click the button,
and it slides right in. And then now we want to
write a rule for our users. So let’s delete read
true write true, because that’s
basically saying do whatever you want
with my database, and that is not very safe. So we’ll start out by writing
a rule for our users path. And we have to make sure to
use the dollar UID wildcard, because that way,
these are rules for any child underneath users. And we’ll set or read
rules and our write rules. I’m going to set read
to true, because I want the users profile data
to be public information. But I only want users to be able
to write their own information. So to do that, I’ll say auth.uid
so the currently authenticated user’s UID is equal to the
wildcard, so dollar UID. And now I can actually
go and simulate this. So I’ll go and simulate a read. So I’ll make sure that /users–
and then this is slash the key for Margaret. And we can even
simulate authentication. For now, I’m going to turn this
off, and then I’m going to run. And you can see that
a read was allowed, because reads are public. But now if I try to
do a write and run, the write was
denied, because you have to be authenticated
to read your own data. So now if I turn
on authentication and I use the same key that I’m
trying to access, and I run, you can see that the
rule was allowed, because the user is allowed
to modify their own data. So now let’s write
a rule to establish the foreign key like construct. I’ll write a rule for
.validate, and we’ll start to go to the root of our database,
and we will read the existing locations by calling
.child of locations. So now I want to make sure
that the newly-added location for the user exists
in the database. So to do that, I’ll call .child. And then from here, I’ll say
new data.child of location, because this is the
newly-posted location data. And then I’ll get its value. And then lastly, at the
end, I’ll call .exists. So this record currently
exists in our lookup. And so right here,
I’m saying location of LA, which does not exist. And then when I run, you can
see that the simulate write was denied even though we were
authenticated, because we are making sure that only the
existing locations exist in our database. But if I move it to an existing
location of SF and hit Run, they both are allowed. Security rules are how
you secure your data against unauthorized users and
protect your data structure. And since security rules can
read data from the database, you can do really
powerful things, like establish foreign
key like constructs. So this is actually
the last episode in the Firebase Database
for SQL Developers series. So if you want to see more,
make sure to like and subscribe, and also leave us a comment and
tell us what you want to learn. So that’s all, and I
will see you all later. Thanks for watching our video. Yeah, we really appreciated it. You should watch
this video, too. And this one. Yeah. And make sure that
you subscribe. It’s really cool.

Danny Hutson

67 thoughts on “Securing your data structure with Security Rules – The Firebase Database For SQL Developers #8

  1. Please tell us what is Firebase good for. You show how to do SQL stuff with Firebase so you must think it can be used for projects that would use SQL otherwise. When is that true? Should I do an ERP system with Firebase to take advantage of the real-time features etc. ?
    Thanks for the great series. Do more, much more 🙂

  2. I loved this series! Very helpful for wrapping my head around the firebase way to do things.

    The biggest black box for me on Firebase right now is server side code. I'd love to see a series on best practices for setting up server queues and jobs (and scaling to multiple workers). Particularly, I'd love to see integration with an API where the API key must remain secret (like sending texts through twilio).

  3. #AskFirebase I would love to see series for server side code. I think this is very important point for any application.

  4. For security rule what will happen if user create a node with the name "rules". Then there will be 2 nested "rules" . Is that supported?

  5. This video was really awesome. For me some parts of the documentation is confusing (specifically the wildcard part), but with your video everything is now clear.

    Thank you and big up to all the Firebase Team 🙂

  6. Is there a way to create an entry in the database using "push()" to auto generate the 'primary key' of the entry, but from the firebase console? I don't have a backend server to deal with that, I'm trying out the front end first, So I'm editing the database manually.

  7. How will you notify the user about the error?.. more javascript code ? or you can just do that on the firebase console

  8. I want to learn how to make a chat application with push notifications in javascript. Any good tutorial available?

  9. Super helpful series please keep em coming!

    Same as Christian I'd like best practice/examples on using and leveraging server queues. Also can you do a video on another very important topic re data security – server side encryption. For enterprise apps this can be a requirement (currently is for our in dev app), keen to understand the options on Firebase for this.

  10. @_davideast #askfirebase Hi David
    How to write security rule to limit child count of a particular path where list of data items are pushed.

  11. How can we use longitude and latitude? Assume we need to list some users who live near by. How can we do that?
    Thanks for your time. It's very helpful.

  12. #AskFirebase I agree with Top Comment about wanting to see server side code, and I will add a specific: I'd like to see server side code for FCM Push Notifications in iOS (for a single device, not using console). This is an immensely obscure topic, because there aren't any good docs or videos on it. For example, the FCM docs don't explain, firstly, how to send a user's token to the server (because, the docs indicate, there are several ways… so, instead of explaining one, they don't explain any; they just say it's "up to you"), and secondly, what the actual structure of the server-side code would be if it was handling the sending of push notifications to single devices remotely. In this video, above, you show the structure of the JSON for the rules clearly. It would be helpful if you did the same for FCM's server side implementation. In general (and y'all may know this, because it is indicated by people's comments), it would be great of you guys to make a good (not bad, not decent—good) video series on FCM Push Notifications for iOS (implementation, sending the tokens, what the server code looks like, how to set up the server, etc).

  13. I'm writing a kid's chat app with parental supervision where parent and child have distinct users/ids/etc. How do I get the parent to read/write the child data?

  14. #AskFirebase qq, the validate security rule applies if the new data comes along with location in this instance, but what happens to validation if the newData doesn't come with location included and the actual provided data is valid? Do we have to write code for in case some of the data is not coming along?

  15. Im struggling on trying to figure out how I can ensure that a 'token' key under the 'User' key can only be decremented by an auth'ed user and never incremented!?

  16. Is the app to have and pass the uid of the current logged in user? If so, then whats the utility of the token and how secure is that the person has access to their own UID?

  17. thanks for your video. I have one question. I want to count something like "Group by" from sql. as It show birthday from customer collection each month. how can I do that? nosql concept is different about sql

  18. What If we are not using built in Auth? we have custom auth at app level. How do we secure db?

  19. hi some one know how insert may own key in the user path, because the firebase create a generic key when we uso the push

  20. Awesome content and thanks for making such a great video. Learnt a lot from this and from multipath and will definitely going to use in my project

  21. I would like to see how to use firebase with angular2/4, as I'm struggling with simple features like reverse sorting.

  22. Dear Firebase,

    Can you please make a part 2 of this video about Cloud Firestore security rules? I'm so confused about them!

  23. Pls help.
    How I can set security rule like this:
    {
    "rules": {
    ".read": true,
    ".write": allow only incoming data from "www.example.com" and block incoming from other sites
    }
    }

  24. I know it's been quite some time since you did this series. However, I'd love to see more. Specifically, I'd love for you to tell us how to do inserts statements. I'd also love to see you screen-cast the process of setting up a firebase project, taking a SQL Schema and implementing it in firebase, in the simulator, and then building queries and rules in the simulator. Then taking it all to a simple application. Something a bit more complex than a chat app would be good. Do this with complete screenshots of the Firebase site.

    I will say that what you have done is great! We just want more!….

  25. #AskFirebase thanks for the videos! I'm new to code and learning Swift. Have you made any Firebase database tutorials that I could watch or articles that I could read that go into more detail on this topic?

  26. Is it possible to restrict the access to my database only to specific(s) domain(s) and/or IP(s)??? I would really like to do this…

  27. Does anyone have any idea why some of the data pushed to the realtime database cuts off, example i had a web app that retrieves and store contact information along with a message,typed by the user,the email address entered was "[email protected]" but it cuts off half the "m",so it looks like "n" as in .con and then the message it tells me when i hover over it it's 257 characters long but it shows 42 characters only

  28. #AskFirebase I added database to my app but whenever I try to open database from app it is showing : Please allow permission to access Database from firebase account. Please tell me how to give permission.

  29. Usually, I think this was a poor video. Everybody who is watching this is thinking the same thing, "How do I authenticate users and give them a $uid?" But, it wasn't mentioned at all.

  30. It really hurts me when people speak this imprecisely, especially engineers. "You can see that the rule was allowed because the user is allowed to modify their own data."

  31. How i can secure firebase storage with security rules?
    1) I want using unique key user can download pics.
    2) I want user can see there picture in website but not download.so I want protect download URL, only those user have key can download pictures.

  32. Is it possible to impose two different rules on two different kind of user tables in firebase for instance userset "users" with one set of rules and userset"users1" with a different set of rules. And how to in firebase database rules section.

    Basically how to nest/cascade separate rules for separate userset

Leave a Reply

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