React devs might find this archived course helpful to reference, but this course has been updated! We now recommend you take the Firebase Fundamentals course.
Transcript from the "Security Rules Introduction" Lesson
[00:00:00]
>> Steve Kinney: So up until now, our database has been wide open and free for anyone to do whatever to anything. That's cool for doing development, but not really a long term game plan cuz people on the Internet are bad. And so we're gonna talk a little about how we actually set up the kind of security rules for our database.
[00:00:26] We basically need to find what a given user is allowed to do, and Firebase enforces all the rest of it for us. So let's look at what security rules look like for Cloud Firestore. So, you have the service which is Cloud Firestore, and then this variable there in the curly brackets that database says which database to match.
[00:00:52] Now, right now in Cloud Firestore there is only one database and it's default. This is I think more future proofing so if they ever offer multiple databases, that can be a thing. But for right now there is one database, so that variable of which database will always be default.
[00:01:11] So for the default database and then we can have some additional rules in there. Now there are a bunch of different actions that we can whitelist. By default, everything, once everything is blacklisted, you turn on certain abilities, right? Really you have read and write, right? So if you turn on read there is the ability to get a given document or to list all of the documents in a collection.
[00:01:42] Read is both of them, get and list are the two more granular options. So if you turn on read, you're gonna get both the ability to get a single document, as well as all the ones in a collection. But you can say, okay, they can't see all the documents in this collection, but they know exactly which one they want, then they can go ahead and get that one.
[00:02:02] So if you had file, like maybe you had all of, making a Google Docs clone. You have all the documents in a collection, right? And maybe you keep those IDs on the user profile and so, okay, if you know which one already, you can go and get it, but you're not going to be able to scan through all of them.
[00:02:22] And then for write, if you turn on write, they have all the ability to create, update and delete. But you can also get granular if you want and say, okay, I want this rule for creating, this other rule for updating, and nobody can delete. And like, you can get granular if you want.
[00:02:38] Or, you can kind of like batch them all in either read or write. So we haven't talked too much about sub-collections yet, but we can see if you nest them they kind of extend from the previous one. So this would be a comment sub-collection under posts. The other thing to notice is that we have these variables in there, right, these dynamic segments.
[00:03:00] So postId will give you a variable called postId you can work with and do logic with as well. And comments will be the comment idea in that case. And you can also see that we're starting to get some of the logic in there, we'll allow read or write if in some condition we haven't written yet.
[00:03:20] So for a given comment, if whatever condition we haven't written yet is met, they can both read and write to them. If you want to just start matching all the way down, like we know that we can go an arbitrary depth of collection, document, collection, document. This document=**, we'll just go the rest to the way down for the rules.
[00:03:41] So you can get very specific. Or you can batch go through all of them. So here's one that we might very well need very soon. This is a little different than what we're actually gonna implement. But this is for any of the posts that they can read and/or write to them only if.
[00:04:03] So we have this request object. This is the request coming into the database that has the auth. So only if the request.auth.uid is not null. So this would be, a user can read or write to any post in the post collections as long as they're logged in. Right.
[00:04:22] If they're not logged in, they can't even read. So we're gonna have one where anyone who visits the page can read but if they wanna create one, then they are gonna have to be logged in. And if they're gonna wanna delete one, they're gonna have to own that one.
[00:04:35] So we're gonna get little bit more granular than this. But it starts to show you how the conditional logic works and how we can start to define some of these rules. This one is for modifying only own data. So in this case, this would be for a user's profile.
[00:04:50] We can create one, as long as they're logged in anyone can create, you know, create one for that user. But in order to read that profile update or delete it, the request.auth.uid needs to equal the uid of that document, the id of that document. Right, so you can kinda build up the kinda more granular logic as you go, you could also do a little bit of validation, right.
[00:05:13] So resource.data will be all the fields that are currently in the database, right, so that it is as it already sits. If that document already exists. Request.resource.data will have the incoming changes. Right so, if they're creating one it's only request.resource.data, but if they were deleting or modifying it, then we could see, like, okay, I want to look at either one of those.
[00:05:39] So, you can kind of get a little bit like, you wanna say okay, only if they have the secret API key for that document or something like that, right. So you can check ones stored on there. You can get really specific to be like, okay, if there is a user document that has an admin bit, turn to true, then they can do these things.
[00:05:58] You can kind of be able to look at different documents and figure some of this stuff out like that. You can actually access other documents as well. So for instance, we have that request off that uid which tells us which user, we can go ahead, look at a user profile, which we're going to create later which is this a document about a user.
[00:06:16] And we say, okay are they in admin, do they own this document? So on and so forth and so you can get pretty logical, we're going to keep, we're going to get. Kind of like to intermediate depth here, we're not gonna like pull from other documents, but we are gonna have those different stages, like anyone can read, only owner can delete, anyone who is logged in can create, so on and so forth.
[00:06:38] But you can actually like query other things for permissions. So you can say okay, this user, what documents do they own? Is this post in the list of ones created by that user? If so, they can do this thing, so on and so forth. So you can have three different users who are allowed to go ahead and delete a given one, right?
[00:06:54] And so you can structure your data in different ways, you can query other documents to figure out what happens in the security rule.
>> Steve Kinney: Security rules are all or nothing, if anything. By a default, everything is blacklisted. If any rule, if you have two conditions, right? If any of them are true, then the user can do that thing, right?
[00:07:16] So if you have two duplicate statements, and it's false in one case, true in the other, they can do it. So you do need to be a little bit careful. You can also do things like limiting the size, so like for instance we know that you pay based on the size of the query that you’re getting back, so you could put security rules in place like hey, at most you know, as long as the limit is 10 or less, cool.
[00:07:41] Otherwise if they try to pull all 60 million, not cool, right? And see you can start to limit like all sorts of other things, like how many they get in and so on and so forth. Cool, this is what we have right now. This is every document in the database.
[00:08:01] The one other text notes that I didn't mention, you can actually write functions as well, effectively. This is not JavaScript obviously, but you can write functions that look like JavaScript. For some of the more complicated ones, if you find yourself reusing it, you can start to pull it out into functions as well.
[00:08:15] But this is what we have right now in our database, which is for that default database, the only database, for any document, allow whoever and whatever to read and write, no matter what, with no conditions. So yeah, we don't want to show that to production. We are gonna want to get a little bit more specific.
[00:08:31] And as we add other collections to our database, we're gonna need to refine these rules a little bit. But the very least, we can get to a good start here.