Role-based user authorization or access control, will give you fine-grained control over user permissions for Firebase users.  In this lesson we are going to give Firebase users 3 different roles - reader, author, and admin.

Full Lesson: https://angularfirebase.com/lessons/role-based-permissions-and-authorization-with-firebase-auth/

We will cover all four of these strategies in this lesson.
- Hide HTML elements
- Prevent actions 
- Restrict routes with router guards
- Create backend Firebase database rules.
2024-02-04T08:12:47.346Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
a1ce7930-3785-4be9-894d-d46d0fcf4f38
a186c500ae2d28a98085015c05b73a05881dcd1924c1b9955295025a3ef9c7d8
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Role based user authorization can give you fine grain control over which actions a user can perform in your app.
Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users.
In this episode, we're going to implement role based access control with Firebase and Angular 4.
Our users are gonna have 3 different roles.
The admin role can read and write anything.
Author role can read and edit but not delete, and the reader can only read data.
Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class.
We'll do this by saving our own custom data to the real time database.
And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute.
In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin.
Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object.
By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault.
So a new user will look like this when they sign up in the database.
So now we can build an auth service to actually log in and log out the user.
We're going to use Google OAuth as the login method.
So we import the AngularFire database as well as AngularFire auth and our custom user class.
And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable.
This will give us more flexibility when we start working with router guards.
Inside the service constructor, we subscribe to the AngularFire auth auth state observable.
Then we can add switch map which will give us access to the auth user ID.
Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID.
If the auth object is undefined, we just return a null observable.
Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject.
If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null.
From here, we'll add a method for the user to sign in and sign out.
I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation.
The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there.
We can do this by creating a new user object and then we'll check the database to see if this data is already defined.
And if it's not, we'll go ahead and update it with the default data from this class.
So this code will only run when we have a brand new user signing up for the first time.
With that out of the way, we can actually start building some authorization rules.
Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts.
We can create a post service to handle this logic.
So we'll import the AngularFire database, our auth service, as well as Lodash.
We set a variable user roles which is an array of the roles that are actually assigned to the current user.
We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings.
This will make the code for our rules a little less verbose.
The next step is to create a couple functions to actually get the data from the database.
And then we can finally start writing some rules related to this data.
First, we're going to write a helper function which is going to see if there are any matches between 2 arrays.
The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles.
This makes the authorization logic very straightforward.
We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles.
For example, the can delete rule only allows admin users.
So if an author or reader user tries to perform this action, it'll return false.
So we can lock down specific actions in the Type grip directly by wrapping them in an if statement.
In this case, users can only edit post if the can edit rule returns true.
If not, it'll just say action prevented.
And we can also perform the same logic for deleting post just using the can delete rule.
If we go into the app, we can see we're currently logged in with just the reader role.
So if we try to edit or delete a post, we'll see this action prevented message in the console.
But if we go into the database and give this user the author role, we should get different results.
So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete.
But we should have access to edit the post.
So we click edit, we go in here, and we edit the data and it should update in the database.
When we go back we can confirm the post does have the new text that we just entered.
Then we can go ahead and add the admin role in the database and we should have access to now delete the post.
When we click delete this time we can see the post is deleted and we don't get any kind of error in the console.
It's also important to point out that we could just hide the delete button from the DOM altogether.
And we can do this by using n g f along with the can delete function that we had defined in the post service.
So just keep that in mind as an option when you're securing data on the front end.
Another option you have for managing roles is with router guards.
So here we're gonna build a router guard that only allows the author role to access a certain route.
The logic is very similar to what you just saw in the post service.
We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not.
Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message.
So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false.
If it's false, then they won't be able to access app route.
So we can apply it to individual routes by going into our app router.
First, make sure the guard is in your provider's array.
And then on individual routes, you can add a can activate array and add that guard to it.
If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console.
And the last thing we're gonna look at is securing the database on the back end.
We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked.
As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules.
The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here.
First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database.
And we do this by traversing the database with the root variable which is provided by Firebase.
For writing data, first, we set the rule for the author.
So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile.
Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want.
That's it for role based access control at Firebase.
If this video helped you, please like and subscribe.
And if you want the full code, head over to angularfirebase.com.
And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro.
Thanks for watching, and I'll talk to you soon.

Speaker 0: Role based user authorization can give you fine grain control over which actions a user can perform in your app. Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users. In this episode, we're going to implement role based access control with Firebase and Angular 4. Our users are gonna have 3 different roles. The admin role can read and write anything.

Author role can read and edit but not delete, and the reader can only read data. Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class. We'll do this by saving our own custom data to the real time database. And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute. In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin.

Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object. By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault. So a new user will look like this when they sign up in the database. So now we can build an auth service to actually log in and log out the user. We're going to use Google OAuth as the login method.

So we import the AngularFire database as well as AngularFire auth and our custom user class. And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable. This will give us more flexibility when we start working with router guards. Inside the service constructor, we subscribe to the AngularFire auth auth state observable. Then we can add switch map which will give us access to the auth user ID.

Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID. If the auth object is undefined, we just return a null observable. Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject. If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null. From here, we'll add a method for the user to sign in and sign out.

I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation. The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there. We can do this by creating a new user object and then we'll check the database to see if this data is already defined. And if it's not, we'll go ahead and update it with the default data from this class. So this code will only run when we have a brand new user signing up for the first time.

With that out of the way, we can actually start building some authorization rules. Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts. We can create a post service to handle this logic. So we'll import the AngularFire database, our auth service, as well as Lodash. We set a variable user roles which is an array of the roles that are actually assigned to the current user.

We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings. This will make the code for our rules a little less verbose. The next step is to create a couple functions to actually get the data from the database. And then we can finally start writing some rules related to this data. First, we're going to write a helper function which is going to see if there are any matches between 2 arrays.

The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles. This makes the authorization logic very straightforward. We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles. For example, the can delete rule only allows admin users. So if an author or reader user tries to perform this action, it'll return false.

So we can lock down specific actions in the Type grip directly by wrapping them in an if statement. In this case, users can only edit post if the can edit rule returns true. If not, it'll just say action prevented. And we can also perform the same logic for deleting post just using the can delete rule. If we go into the app, we can see we're currently logged in with just the reader role.

So if we try to edit or delete a post, we'll see this action prevented message in the console. But if we go into the database and give this user the author role, we should get different results. So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete. But we should have access to edit the post. So we click edit, we go in here, and we edit the data and it should update in the database.

When we go back we can confirm the post does have the new text that we just entered. Then we can go ahead and add the admin role in the database and we should have access to now delete the post. When we click delete this time we can see the post is deleted and we don't get any kind of error in the console. It's also important to point out that we could just hide the delete button from the DOM altogether. And we can do this by using n g f along with the can delete function that we had defined in the post service.

So just keep that in mind as an option when you're securing data on the front end. Another option you have for managing roles is with router guards. So here we're gonna build a router guard that only allows the author role to access a certain route. The logic is very similar to what you just saw in the post service. We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not.

Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message. So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false. If it's false, then they won't be able to access app route. So we can apply it to individual routes by going into our app router. First, make sure the guard is in your provider's array.

And then on individual routes, you can add a can activate array and add that guard to it. If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console. And the last thing we're gonna look at is securing the database on the back end. We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked. As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules.

The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here. First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database. And we do this by traversing the database with the root variable which is provided by Firebase. For writing data, first, we set the rule for the author. So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile.

Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want. That's it for role based access control at Firebase. If this video helped you, please like and subscribe. And if you want the full code, head over to angularfirebase.com. And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro.

Thanks for watching, and I'll talk to you soon.
Role based user authorization can give you fine grain control over which actions a user can perform in your app. Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users. In this episode, we're going to implement role based access control with Firebase and Angular 4. Our users are gonna have 3 different roles. The admin role can read and write anything. Author role can read and edit but not delete, and the reader can only read data. Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class.
We'll do this by saving our own custom data to the real time database. And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute. In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin.
databases
Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object. By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault.
So a new user will look like this when they sign up in the database. So now we can build an auth service to actually log in and log out the user. We're going to use Google OAuth as the login method. So we import the AngularFire database as well as AngularFire auth and our custom user class.
databases
And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable. This will give us more flexibility when we start working with router guards. Inside the service constructor, we subscribe to the AngularFire auth auth state observable. Then we can add switch map which will give us access to the auth user ID.
Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID. If the auth object is undefined, we just return a null observable. Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject.
data
databases
data management
If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null. From here, we'll add a method for the user to sign in and sign out. I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation. The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there. We can do this by creating a new user object and then we'll check the database to see if this data is already defined. And if it's not, we'll go ahead and update it with the default data from this class. So this code will only run when we have a brand new user signing up for the first time.
databases
data management
With that out of the way, we can actually start building some authorization rules.
Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts. We can create a post service to handle this logic. So we'll import the AngularFire database, our auth service, as well as Lodash. We set a variable user roles which is an array of the roles that are actually assigned to the current user. We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings. This will make the code for our rules a little less verbose. The next step is to create a couple functions to actually get the data from the database. And then we can finally start writing some rules related to this data. First, we're going to write a helper function which is going to see if there are any matches between 2 arrays. The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles.
databases
data
programming
data management
operations
This makes the authorization logic very straightforward. We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles. For example, the can delete rule only allows admin users. So if an author or reader user tries to perform this action, it'll return false. So we can lock down specific actions in the Type grip directly by wrapping them in an if statement. In this case, users can only edit post if the can edit rule returns true. If not, it'll just say action prevented. And we can also perform the same logic for deleting post just using the can delete rule. If we go into the app, we can see we're currently logged in with just the reader role. So if we try to edit or delete a post, we'll see this action prevented message in the console. But if we go into the database and give this user the author role, we should get different results. So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete. But we should have access to edit the post. So we click edit, we go in here, and we edit the data and it should update in the database. When we go back we can confirm the post does have the new text that we just entered. Then we can go ahead and add the admin role in the database and we should have access to now delete the post. When we click delete this time we can see the post is deleted and we don't get any kind of error in the console. It's also important to point out that we could just hide the delete button from the DOM altogether.
And we can do this by using n g f along with the can delete function that we had defined in the post service. So just keep that in mind as an option when you're securing data on the front end. Another option you have for managing roles is with router guards. So here we're gonna build a router guard that only allows the author role to access a certain route. The logic is very similar to what you just saw in the post service. We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not.
logic
security
logical reasoning
Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message. So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false. If it's false, then they won't be able to access app route. So we can apply it to individual routes by going into our app router. First, make sure the guard is in your provider's array. And then on individual routes, you can add a can activate array and add that guard to it.
If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console. And the last thing we're gonna look at is securing the database on the back end. We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked.
databases
security
As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules.
The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here. First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database. And we do this by traversing the database with the root variable which is provided by Firebase. For writing data, first, we set the rule for the author. So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile. Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want.
data
data management
databases
That's it for role based access control at Firebase. If this video helped you, please like and subscribe. And if you want the full code, head over to angularfirebase.com. And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro.
youtube
Thanks for watching, and I'll talk to you soon.
Role based user authorization can give you fine grain control over which actions a user can perform in your app. Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users. In this episode, we're going to implement role based access control with Firebase and Angular 4. Our users are gonna have 3 different roles. The admin role can read and write anything. Author role can read and edit but not delete, and the reader can only read data. Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class. We'll do this by saving our own custom data to the real time database. And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute. In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin. Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object. By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault. So a new user will look like this when they sign up in the database. So now we can build an auth service to actually log in and log out the user. We're going to use Google OAuth as the login method. So we import the AngularFire database as well as AngularFire auth and our custom user class. And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable. This will give us more flexibility when we start working with router guards. Inside the service constructor, we subscribe to the AngularFire auth auth state observable. Then we can add switch map which will give us access to the auth user ID. Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID. If the auth object is undefined, we just return a null observable. Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject. If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null. From here, we'll add a method for the user to sign in and sign out. I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation. The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there. We can do this by creating a new user object and then we'll check the database to see if this data is already defined. And if it's not, we'll go ahead and update it with the default data from this class. So this code will only run when we have a brand new user signing up for the first time. With that out of the way, we can actually start building some authorization rules. Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts. We can create a post service to handle this logic. So we'll import the AngularFire database, our auth service, as well as Lodash. We set a variable user roles which is an array of the roles that are actually assigned to the current user. We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings. This will make the code for our rules a little less verbose. The next step is to create a couple functions to actually get the data from the database. And then we can finally start writing some rules related to this data. First, we're going to write a helper function which is going to see if there are any matches between 2 arrays. The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles. This makes the authorization logic very straightforward. We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles. For example, the can delete rule only allows admin users. So if an author or reader user tries to perform this action, it'll return false. So we can lock down specific actions in the Type grip directly by wrapping them in an if statement. In this case, users can only edit post if the can edit rule returns true. If not, it'll just say action prevented. And we can also perform the same logic for deleting post just using the can delete rule. If we go into the app, we can see we're currently logged in with just the reader role. So if we try to edit or delete a post, we'll see this action prevented message in the console. But if we go into the database and give this user the author role, we should get different results. So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete. But we should have access to edit the post. So we click edit, we go in here, and we edit the data and it should update in the database. When we go back we can confirm the post does have the new text that we just entered. Then we can go ahead and add the admin role in the database and we should have access to now delete the post. When we click delete this time we can see the post is deleted and we don't get any kind of error in the console. It's also important to point out that we could just hide the delete button from the DOM altogether. And we can do this by using n g f along with the can delete function that we had defined in the post service. So just keep that in mind as an option when you're securing data on the front end. Another option you have for managing roles is with router guards. So here we're gonna build a router guard that only allows the author role to access a certain route. The logic is very similar to what you just saw in the post service. We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not. Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message. So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false. If it's false, then they won't be able to access app route. So we can apply it to individual routes by going into our app router. First, make sure the guard is in your provider's array. And then on individual routes, you can add a can activate array and add that guard to it. If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console. And the last thing we're gonna look at is securing the database on the back end. We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked. As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules. The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here. First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database. And we do this by traversing the database with the root variable which is provided by Firebase. For writing data, first, we set the rule for the author. So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile. Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want. That's it for role based access control at Firebase. If this video helped you, please like and subscribe. And if you want the full code, head over to angularfirebase.com. And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro. Thanks for watching, and I'll talk to you soon.
Role
role
based
based
user
user
authorization
authorization
can
can
give
give
you
you
fine
fine
grain
grain
control
control
over
over
which
which
actions
actions
a
a
user
user
can
can
perform
perform
in
in
your
your
app.
app
Many
many
apps
apps
use
use
this
this
strategy
strategy
such
such
as
as
Stack
stack
Overflow
overflow
and
and
Reddit
reddit
to
to
control
control
the
the
types
types
of
of
data
data
that
that
can
can
be
be
modified
modified
by
by
users.
users
In
in
this
this
episode,
episode
we're
we're
going
going
to
to
implement
implement
role
role
based
based
access
access
control
control
with
with
Firebase
firebase
and
and
Angular
angular
4.
4
Our
our
users
users
are
are
gonna
gonna
have
have
3
3
different
different
roles.
roles
The
the
admin
admin
role
role
can
can
read
read
and
and
write
write
anything.
anything
Author
author
role
role
can
can
read
read
and
and
edit
edit
but
but
not
not
delete,
delete
and
and
the
the
reader
reader
can
can
only
only
read
read
data.
data
Since
since
we
we
can't
can't
actually
actually
edit
edit
the
the
data
data
on
on
the
the
Firebase
firebase
auth
auth
object,
object
we
we
need
need
to
to
create
create
our
our
own
own
custom
custom
user
user
class.
class
We'll
we'll
do
do
this
this
by
by
saving
saving
our
our
own
own
custom
custom
data
data
to
to
the
the
real
real
time
time
database.
database
And
and
in
in
the
the
user
user
object,
object
we'll
we'll
have
have
a
a
roles
roles
object
object
which
which
can
can
either
either
have
have
an
an
author,
author
reader,
reader
or
or
admin
admin
attribute.
attribute
In
in
the
the
Angular
angular
app,
app
I'm
i'm
going
going
to
to
use
use
a
a
TypeScript
typescript
interface
interface
to
to
make
make
sure
sure
that
that
the
the
user
user
roles
roles
can't
can't
be
be
anything
anything
other
other
than
than
a
a
reader,
reader
author,
author
or
or
admin.
admin
Then
then
I'm
i'm
creating
creating
a
a
custom
custom
user
user
class,
class
which
which
is
is
where
where
we
we
can
can
define
define
any
any
custom
custom
data
data
we
we
wanna
wanna
add
add
to
to
the
the
user
user
object.
object
By
by
default,
default
we'll
we'll
pass
pass
the
the
constructor
constructor
the
the
Firebase
firebase
auth
auth
data
data
and
and
use
use
that
that
to
to
set
set
an
an
email
email
photo
photo
URL,
url
and
and
then
then
we'll
we'll
set
set
the
the
reader
reader
value
value
to
to
true
true
by
by
Vault.
vault
So
so
a
a
new
new
user
user
will
will
look
look
like
like
this
this
when
when
they
they
sign
sign
up
up
in
in
the
the
database.
database
So
so
now
now
we
we
can
can
build
build
an
an
auth
auth
service
service
to
to
actually
actually
log
log
in
in
and
and
log
log
out
out
the
the
user.
user
We're
we're
going
going
to
to
use
use
Google
google
OAuth
oauth
as
as
the
the
login
login
method.
method
So
so
we
we
import
import
the
the
AngularFire
angularfire
database
database
as
as
well
well
as
as
AngularFire
angularfire
auth
auth
and
and
our
our
custom
custom
user
user
class.
class
And
and
we're
we're
gonna
gonna
set
set
our
our
current
current
user
user
as
as
a
a
behavior
behavior
subject
subject
instead
instead
of
of
the
the
AngularFire
angularfire
auth
auth
observable.
observable
This
this
will
will
give
give
us
us
more
more
flexibility
flexibility
when
when
we
we
start
start
working
working
with
with
router
router
guards.
guards
Inside
inside
the
the
service
service
constructor,
constructor
we
we
subscribe
subscribe
to
to
the
the
AngularFire
angularfire
auth
auth
auth
auth
state
state
observable.
observable
Then
then
we
we
can
can
add
add
switch
switch
map
map
which
which
will
will
give
give
us
us
access
access
to
to
the
the
auth
auth
user
user
ID.
id
Then
then
and
and
we
we
can
can
return
return
the
the
location
location
in
in
the
the
database
database
that
that
has
has
this
this
user
user
data,
data
which
which
in
in
this
this
case
case
is
is
a
a
user
user
collection
collection
followed
followed
by
by
the
the
user
user
ID.
id
If
if
the
the
auth
auth
object
object
is
is
undefined,
undefined
we
we
just
just
return
return
a
a
null
null
observable.
observable
Then
then
we
we
can
can
call
call
subscribe
subscribe
and
and
whatever
whatever
we
we
get
get
back
back
is
is
what
what
we'll
we'll
apply
apply
to
to
the
the
behavior
behavior
subject.
subject
If
if
the
the
user
user
is
is
logged
logged
in,
in
this
this
will
will
be
be
the
the
data
data
from
from
the
the
database,
database
and
and
if
if
they're
they're
not
not
signed
signed
in,
in
it'll
it'll
just
just
be
be
null.
null
From
from
here,
here
we'll
we'll
add
add
a
a
method
method
for
for
the
the
user
user
to
to
sign
sign
in
in
and
and
sign
sign
out.
out
I'm
i'm
I'm
i'm
just
just
gonna
gonna
go
go
over
over
this
this
quickly
quickly
because
because
it's
it's
the
the
standard
standard
information
information
you'll
you'll
find
find
in
in
the
the
AngularFire
angularfire
2
2
documentation.
documentation
The
the
only
only
difference
difference
is
is
when
when
the
the
user
user
logs
logs
in,
in
we
we
want
want
to
to
update
update
the
the
database
database
with
with
whatever
whatever
user
user
information
information
we
we
wanna
wanna
save
save
there.
there
We
we
can
can
do
do
this
this
by
by
creating
creating
a
a
new
new
user
user
object
object
and
and
then
then
we'll
we'll
check
check
the
the
database
database
to
to
see
see
if
if
this
this
data
data
is
is
already
already
defined.
defined
And
and
if
if
it's
it's
not,
not
we'll
we'll
go
go
ahead
ahead
and
and
update
update
it
it
with
with
the
the
default
default
data
data
from
from
this
this
class.
class
So
so
this
this
code
code
will
will
only
only
run
run
when
when
we
we
have
have
a
a
brand
brand
new
new
user
user
signing
signing
up
up
for
for
the
the
first
first
time.
time
With
with
that
that
out
out
of
of
the
the
way,
way
we
we
can
can
actually
actually
start
start
building
building
some
some
authorization
authorization
rules.
rules
Our
our
database
database
has
has
some
some
posts
posts
in
in
it,
it
and
and
we
we
wanna
wanna
limit
limit
access
access
to
to
who
who
can
can
create,
create
update,
update
and
and
delete
delete
these
these
posts.
posts
We
we
can
can
create
create
a
a
post
post
service
service
to
to
handle
handle
this
this
logic.
logic
So
so
we'll
we'll
import
import
the
the
AngularFire
angularfire
database,
database
our
our
auth
auth
service,
service
as
as
well
well
as
as
Lodash.
lodash
We
we
set
set
a
a
variable
variable
user
user
roles
roles
which
which
is
is
an
an
array
array
of
of
the
the
roles
roles
that
that
are
are
actually
actually
assigned
assigned
to
to
the
the
current
current
user.
user
We
we
can
can
define
define
this
this
variable
variable
by
by
subscribing
subscribing
to
to
the
the
user
user
from
from
our
our
auth
auth
service
service
and
and
then
then
we'll
we'll
map
map
the
the
roles
roles
down
down
to
to
an
an
array
array
of
of
strings.
strings
This
this
will
will
make
make
the
the
code
code
for
for
our
our
rules
rules
a
a
little
little
less
less
verbose.
verbose
The
the
next
next
step
step
is
is
to
to
create
create
a
a
couple
couple
functions
functions
to
to
actually
actually
get
get
the
the
data
data
from
from
the
the
database.
database
And
and
then
then
we
we
can
can
finally
finally
start
start
writing
writing
some
some
rules
rules
related
related
to
to
this
this
data.
data
First,
first
we're
we're
going
going
to
to
write
write
a
a
helper
helper
function
function
which
which
is
is
going
going
to
to
see
see
if
if
there
there
are
are
any
any
matches
matches
between
between
2
2
arrays.
arrays
The
the
reason
reason
is
is
that
that
every
every
rule
rule
is
is
going
going
to
to
have
have
an
an
array
array
of
of
allowed
allowed
roles
roles
and
and
we
we
wanna
wanna
make
make
sure
sure
those
those
roles
roles
match
match
the
the
actual
actual
user
user
roles.
roles
This
this
makes
makes
the
the
authorization
authorization
logic
logic
very
very
straightforward.
straightforward
We
we
just
just
define
define
an
an
array
array
of
of
the
the
allowed
allowed
roles
roles
and
and
then
then
we
we
call
call
our
our
helper
helper
function
function
to
to
see
see
if
if
there's
there's
a
a
match
match
between
between
those
those
roles
roles
and
and
the
the
user's
user's
roles.
roles
For
for
example,
example
the
the
can
can
delete
delete
rule
rule
only
only
allows
allows
admin
admin
users.
users
So
so
if
if
an
an
author
author
or
or
reader
reader
user
user
tries
tries
to
to
perform
perform
this
this
action,
action
it'll
it'll
return
return
false.
false
So
so
we
we
can
can
lock
lock
down
down
specific
specific
actions
actions
in
in
the
the
Type
type
grip
grip
directly
directly
by
by
wrapping
wrapping
them
them
in
in
an
an
if
if
statement.
statement
In
in
this
this
case,
case
users
users
can
can
only
only
edit
edit
post
post
if
if
the
the
can
can
edit
edit
rule
rule
returns
returns
true.
true
If
if
not,
not
it'll
it'll
just
just
say
say
action
action
prevented.
prevented
And
and
we
we
can
can
also
also
perform
perform
the
the
same
same
logic
logic
for
for
deleting
deleting
post
post
just
just
using
using
the
the
can
can
delete
delete
rule.
rule
If
if
we
we
go
go
into
into
the
the
app,
app
we
we
can
can
see
see
we're
we're
currently
currently
logged
logged
in
in
with
with
just
just
the
the
reader
reader
role.
role
So
so
if
if
we
we
try
try
to
to
edit
edit
or
or
delete
delete
a
a
post,
post
we'll
we'll
see
see
this
this
action
action
prevented
prevented
message
message
in
in
the
the
console.
console
But
but
if
if
we
we
go
go
into
into
the
the
database
database
and
and
give
give
this
this
user
user
the
the
author
author
role,
role
we
we
should
should
get
get
different
different
results.
results
So
so
now
now
that
that
we
we
have
have
the
the
author
author
permission,
permission
we
we
can
can
try
try
to
to
delete
delete
a
a
post,
post
but
but
we'll
we'll
still
still
get
get
the
the
same
same
message
message
because
because
we're
we're
not
not
authorized
authorized
to
to
delete.
delete
But
but
we
we
should
should
have
have
access
access
to
to
edit
edit
the
the
post.
post
So
so
we
we
click
click
edit,
edit
we
we
go
go
in
in
here,
here
and
and
we
we
edit
edit
the
the
data
data
and
and
it
it
should
should
update
update
in
in
the
the
database.
database
When
when
we
we
go
go
back
back
we
we
can
can
confirm
confirm
the
the
post
post
does
does
have
have
the
the
new
new
text
text
that
that
we
we
just
just
entered.
entered
Then
then
we
we
can
can
go
go
ahead
ahead
and
and
add
add
the
the
admin
admin
role
role
in
in
the
the
database
database
and
and
we
we
should
should
have
have
access
access
to
to
now
now
delete
delete
the
the
post.
post
When
when
we
we
click
click
delete
delete
this
this
time
time
we
we
can
can
see
see
the
the
post
post
is
is
deleted
deleted
and
and
we
we
don't
don't
get
get
any
any
kind
kind
of
of
error
error
in
in
the
the
console.
console
It's
it's
also
also
important
important
to
to
point
point
out
out
that
that
we
we
could
could
just
just
hide
hide
the
the
delete
delete
button
button
from
from
the
the
DOM
dom
altogether.
altogether
And
and
we
we
can
can
do
do
this
this
by
by
using
using
n
n
g
g
f
f
along
along
with
with
the
the
can
can
delete
delete
function
function
that
that
we
we
had
had
defined
defined
in
in
the
the
post
post
service.
service
So
so
just
just
keep
keep
that
that
in
in
mind
mind
as
as
an
an
option
option
when
when
you're
you're
securing
securing
data
data
on
on
the
the
front
front
end.
end
Another
another
option
option
you
you
have
have
for
for
managing
managing
roles
roles
is
is
with
with
router
router
guards.
guards
So
so
here
here
we're
we're
gonna
gonna
build
build
a
a
router
router
guard
guard
that
that
only
only
allows
allows
the
the
author
author
role
role
to
to
access
access
a
a
certain
certain
route.
route
The
the
logic
logic
is
is
very
very
similar
similar
to
to
what
what
you
you
just
just
saw
saw
in
in
the
the
post
post
service.
service
We
we
first
first
subscribe
subscribe
to
to
the
the
current
current
user
user
from
from
our
our
auth
auth
service
service
and
and
then
then
we
we
map
map
the
the
roles
roles
down
down
to
to
a
a
boolean
boolean
which
which
will
will
return
return
true
true
if
if
they
they
have
have
the
the
author
author
role
role
and
and
then
then
false
false
if
if
they
they
do
do
not.
not
Then
then
we
we
can
can
use
use
the
the
RxJS
rxjs
do
do
operator
operator
to
to
run
run
some
some
arbitrary
arbitrary
code
code
which
which
is
is
useful
useful
if
if
you
you
wanna
wanna
redirect
redirect
the
the
user
user
or
or
raise
raise
like
like
a
a
toast
toast
message.
message
So
so
when
when
a
a
user
user
tries
tries
to
to
navigate
navigate
to
to
this
this
route,
route
Angular
angular
will
will
subscribe
subscribe
to
to
this
this
observable,
observable
and
and
it'll
it'll
either
either
return
return
true
true
or
or
false.
false
If
if
it's
it's
false,
false
then
then
they
they
won't
won't
be
be
able
able
to
to
access
access
app
app
route.
route
So
so
we
we
can
can
apply
apply
it
it
to
to
individual
individual
routes
routes
by
by
going
going
into
into
our
our
app
app
router.
router
First,
first
make
make
sure
sure
the
the
guard
guard
is
is
in
in
your
your
provider's
provider's
array.
array
And
and
then
then
on
on
individual
individual
routes,
routes
you
you
can
can
add
add
a
a
can
can
activate
activate
array
array
and
and
add
add
that
that
guard
guard
to
to
it.
it
If
if
we
we
try
try
to
to
navigate
navigate
to
to
this
this
route
route
without
without
the
the
author
author
role,
role
we'll
we'll
see
see
the
the
route
route
is
is
blocked
blocked
and
and
will
will
also
also
get
get
this
this
route
route
prevented
prevented
message
message
in
in
the
the
console.
console
And
and
the
the
last
last
thing
thing
we're
we're
gonna
gonna
look
look
at
at
is
is
securing
securing
the
the
database
database
on
on
the
the
back
back
end.
end
We
we
can
can
use
use
Firebase
firebase
database
database
rules
rules
to
to
ensure
ensure
our
our
data
data
integrity
integrity
even
even
if
if
our
our
front
front
end
end
JavaScript
javascript
code
code
is
is
hacked.
hacked
As
as
you
you
can
can
see
see
here,
here
I've
i've
removed
removed
the
the
can
can
delete
delete
rule
rule
from
from
Angular
angular
and
and
our
our
user
user
only
only
has
has
the
the
reader
reader
role
role
so
so
they
they
shouldn't
shouldn't
be
be
able
able
to
to
delete
delete
post,
post
but
but
we
we
still
still
get
get
an
an
error
error
from
from
Firebase
firebase
because
because
we've
we've
set
set
some
some
back
back
end
end
database
database
rules.
rules
The
the
rules
rules
are
are
kind
kind
of
of
hard
hard
to
to
read
read
so
so
I
i
recommend
recommend
going
going
to
to
angularfirebase.com
angularfirebase.com
to
to
get
get
the
the
full
full
code,
code
but
but
we'll
we'll
go
go
through
through
it
it
really
really
quickly
quickly
here.
here
First
first
we
we
set
set
a
a
rule
rule
for
for
reading
reading
data
data
so
so
we
we
make
make
sure
sure
that
that
the
the
user
user
with
with
that
that
auth
auth
ID
id
has
has
the
the
reader
reader
attribute
attribute
in
in
the
the
database.
database
And
and
we
we
do
do
this
this
by
by
traversing
traversing
the
the
database
database
with
with
the
the
root
root
variable
variable
which
which
is
is
provided
provided
by
by
Firebase.
firebase
For
for
writing
writing
data,
data
first,
first
we
we
set
set
the
the
rule
rule
for
for
the
the
author.
author
So
so
so
so
we
we
make
make
sure
sure
that
that
they're
they're
providing
providing
new
new
data,
data
which
which
means
means
they're
they're
not
not
deleting
deleting
the
the
post,
post
and
and
then
then
we
we
traverse
traverse
the
the
database
database
again,
again
making
making
sure
sure
that
that
they
they
have
have
the
the
author
author
role
role
on
on
their
their
profile.
profile
Otherwise,
otherwise
for
for
admin
admin
users,
users
we
we
just
just
need
need
to
to
make
make
sure
sure
that
that
they
they
have
have
the
the
admin
admin
role
role
on
on
their
their
profile,
profile
and
and
they
they
can
can
create,
create
update,
update
or
or
delete
delete
any
any
data
data
that
that
they
they
want.
want
That's
that's
it
it
for
for
role
role
based
based
access
access
control
control
at
at
Firebase.
firebase
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
want
want
the
the
full
full
code,
code
head
head
over
over
to
to
angularfirebase.com.
angularfirebase.com
And
and
if
if
you
you
want
want
access
access
to
to
exclusive
exclusive
content
content
as
as
well
well
as
as
1
1
on
on
1
1
project
project
consulting,
consulting
consider
consider
becoming
becoming
an
an
Angular
angular
Firebase
firebase
pro.
pro
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The speakers discuss user authorization based on roles and create a helper function to match actual roles. They also discuss setting a limit and use a post service to handle authorization processes. The process for updating the database, signing in and out, and deleting a post is discussed, along with managing roles and using router guards for data integrity and secure the database on the back end. A can delete rule is recommended for preventing certain actions in the app, and the speakers recommend using theiva.com for code and access to exclusive content and a 1 on 1 project consulting.
Role-Based User Permissions in Firebase
Role based user authorization can give you fine grain control over which actions a user can perform in your app. Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users. In this episode, we're going to implement role based access control with Firebase and Angular 4. Our users are gonna have 3 different roles. The admin role can read and write anything. Author role can read and edit but not delete, and the reader can only read data. Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class. We'll do this by saving our own custom data to the real time database. And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute. In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin. Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object. By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault. So a new user will look like this when they sign up in the database. So now we can build an auth service to actually log in and log out the user. We're going to use Google OAuth as the login method. So we import the AngularFire database as well as AngularFire auth and our custom user class. And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable. This will give us more flexibility when we start working with router guards. Inside the service constructor, we subscribe to the AngularFire auth auth state observable. Then we can add switch map which will give us access to the auth user ID. Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID. If the auth object is undefined, we just return a null observable. Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject. If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null. From here, we'll add a method for the user to sign in and sign out. I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation. The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there. We can do this by creating a new user object and then we'll check the database to see if this data is already defined. And if it's not, we'll go ahead and update it with the default data from this class. So this code will only run when we have a brand new user signing up for the first time. With that out of the way, we can actually start building some authorization rules. Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts. We can create a post service to handle this logic. So we'll import the AngularFire database, our auth service, as well as Lodash. We set a variable user roles which is an array of the roles that are actually assigned to the current user. We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings. This will make the code for our rules a little less verbose. The next step is to create a couple functions to actually get the data from the database. And then we can finally start writing some rules related to this data. First, we're going to write a helper function which is going to see if there are any matches between 2 arrays. The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles. This makes the authorization logic very straightforward. We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles. For example, the can delete rule only allows admin users. So if an author or reader user tries to perform this action, it'll return false. So we can lock down specific actions in the Type grip directly by wrapping them in an if statement. In this case, users can only edit post if the can edit rule returns true. If not, it'll just say action prevented. And we can also perform the same logic for deleting post just using the can delete rule. If we go into the app, we can see we're currently logged in with just the reader role. So if we try to edit or delete a post, we'll see this action prevented message in the console. But if we go into the database and give this user the author role, we should get different results. So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete. But we should have access to edit the post. So we click edit, we go in here, and we edit the data and it should update in the database. When we go back we can confirm the post does have the new text that we just entered. Then we can go ahead and add the admin role in the database and we should have access to now delete the post. When we click delete this time we can see the post is deleted and we don't get any kind of error in the console. It's also important to point out that we could just hide the delete button from the DOM altogether. And we can do this by using n g f along with the can delete function that we had defined in the post service. So just keep that in mind as an option when you're securing data on the front end. Another option you have for managing roles is with router guards. So here we're gonna build a router guard that only allows the author role to access a certain route. The logic is very similar to what you just saw in the post service. We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not. Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message. So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false. If it's false, then they won't be able to access app route. So we can apply it to individual routes by going into our app router. First, make sure the guard is in your provider's array. And then on individual routes, you can add a can activate array and add that guard to it. If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console. And the last thing we're gonna look at is securing the database on the back end. We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked. As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules. The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here. First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database. And we do this by traversing the database with the root variable which is provided by Firebase. For writing data, first, we set the rule for the author. So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile. Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want. That's it for role based access control at Firebase. If this video helped you, please like and subscribe. And if you want the full code, head over to angularfirebase.com. And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro. Thanks for watching, and I'll talk to you soon.
The speakers discuss user authorization based on roles and create a helper function to match actual roles. They also discuss setting a limit and use a post service to handle authorization processes. The process for updating the database, signing in and out, and deleting a post is discussed, along with managing roles and using router guards for data integrity and secure the database on the back end. A can delete rule is recommended for preventing certain actions in the app, and the speakers recommend using theiva.com for code and access to exclusive content and a 1 on 1 project consulting.

        [INST]
        You are youtuber called Fireship you make engaging high-intensity and entertaining coding tutorials and tech news. 
        you covers a wide range of topics relevant to programmers, aiming to help them learn and improve their skills quickly.
        
        Given the title of the video : Role-Based User Permissions in Firebase 
        and a small summary : The speakers discuss user authorization based on roles and create a helper function to match actual roles. They also discuss setting a limit and use a post service to handle authorization processes. The process for updating the database, signing in and out, and deleting a post is discussed, along with managing roles and using router guards for data integrity and secure the database on the back end. A can delete rule is recommended for preventing certain actions in the app, and the speakers recommend using theiva.com for code and access to exclusive content and a 1 on 1 project consulting.
        [/INST]
        
        Generate the video : Role based user authorization can give you fine grain control over which actions a user can perform in your app. Many apps use this strategy such as Stack Overflow and Reddit to control the types of data that can be modified by users. In this episode, we're going to implement role based access control with Firebase and Angular 4. Our users are gonna have 3 different roles. The admin role can read and write anything. Author role can read and edit but not delete, and the reader can only read data. Since we can't actually edit the data on the Firebase auth object, we need to create our own custom user class. We'll do this by saving our own custom data to the real time database. And in the user object, we'll have a roles object which can either have an author, reader, or admin attribute. In the Angular app, I'm going to use a TypeScript interface to make sure that the user roles can't be anything other than a reader, author, or admin. Then I'm creating a custom user class, which is where we can define any custom data we wanna add to the user object. By default, we'll pass the constructor the Firebase auth data and use that to set an email photo URL, and then we'll set the reader value to true by Vault. So a new user will look like this when they sign up in the database. So now we can build an auth service to actually log in and log out the user. We're going to use Google OAuth as the login method. So we import the AngularFire database as well as AngularFire auth and our custom user class. And we're gonna set our current user as a behavior subject instead of the AngularFire auth observable. This will give us more flexibility when we start working with router guards. Inside the service constructor, we subscribe to the AngularFire auth auth state observable. Then we can add switch map which will give us access to the auth user ID. Then and we can return the location in the database that has this user data, which in this case is a user collection followed by the user ID. If the auth object is undefined, we just return a null observable. Then we can call subscribe and whatever we get back is what we'll apply to the behavior subject. If the user is logged in, this will be the data from the database, and if they're not signed in, it'll just be null. From here, we'll add a method for the user to sign in and sign out. I'm I'm just gonna go over this quickly because it's the standard information you'll find in the AngularFire 2 documentation. The only difference is when the user logs in, we want to update the database with whatever user information we wanna save there. We can do this by creating a new user object and then we'll check the database to see if this data is already defined. And if it's not, we'll go ahead and update it with the default data from this class. So this code will only run when we have a brand new user signing up for the first time. With that out of the way, we can actually start building some authorization rules. Our database has some posts in it, and we wanna limit access to who can create, update, and delete these posts. We can create a post service to handle this logic. So we'll import the AngularFire database, our auth service, as well as Lodash. We set a variable user roles which is an array of the roles that are actually assigned to the current user. We can define this variable by subscribing to the user from our auth service and then we'll map the roles down to an array of strings. This will make the code for our rules a little less verbose. The next step is to create a couple functions to actually get the data from the database. And then we can finally start writing some rules related to this data. First, we're going to write a helper function which is going to see if there are any matches between 2 arrays. The reason is that every rule is going to have an array of allowed roles and we wanna make sure those roles match the actual user roles. This makes the authorization logic very straightforward. We just define an array of the allowed roles and then we call our helper function to see if there's a match between those roles and the user's roles. For example, the can delete rule only allows admin users. So if an author or reader user tries to perform this action, it'll return false. So we can lock down specific actions in the Type grip directly by wrapping them in an if statement. In this case, users can only edit post if the can edit rule returns true. If not, it'll just say action prevented. And we can also perform the same logic for deleting post just using the can delete rule. If we go into the app, we can see we're currently logged in with just the reader role. So if we try to edit or delete a post, we'll see this action prevented message in the console. But if we go into the database and give this user the author role, we should get different results. So now that we have the author permission, we can try to delete a post, but we'll still get the same message because we're not authorized to delete. But we should have access to edit the post. So we click edit, we go in here, and we edit the data and it should update in the database. When we go back we can confirm the post does have the new text that we just entered. Then we can go ahead and add the admin role in the database and we should have access to now delete the post. When we click delete this time we can see the post is deleted and we don't get any kind of error in the console. It's also important to point out that we could just hide the delete button from the DOM altogether. And we can do this by using n g f along with the can delete function that we had defined in the post service. So just keep that in mind as an option when you're securing data on the front end. Another option you have for managing roles is with router guards. So here we're gonna build a router guard that only allows the author role to access a certain route. The logic is very similar to what you just saw in the post service. We first subscribe to the current user from our auth service and then we map the roles down to a boolean which will return true if they have the author role and then false if they do not. Then we can use the RxJS do operator to run some arbitrary code which is useful if you wanna redirect the user or raise like a toast message. So when a user tries to navigate to this route, Angular will subscribe to this observable, and it'll either return true or false. If it's false, then they won't be able to access app route. So we can apply it to individual routes by going into our app router. First, make sure the guard is in your provider's array. And then on individual routes, you can add a can activate array and add that guard to it. If we try to navigate to this route without the author role, we'll see the route is blocked and will also get this route prevented message in the console. And the last thing we're gonna look at is securing the database on the back end. We can use Firebase database rules to ensure our data integrity even if our front end JavaScript code is hacked. As you can see here, I've removed the can delete rule from Angular and our user only has the reader role so they shouldn't be able to delete post, but we still get an error from Firebase because we've set some back end database rules. The rules are kind of hard to read so I recommend going to angularfirebase.com to get the full code, but we'll go through it really quickly here. First we set a rule for reading data so we make sure that the user with that auth ID has the reader attribute in the database. And we do this by traversing the database with the root variable which is provided by Firebase. For writing data, first, we set the rule for the author. So so we make sure that they're providing new data, which means they're not deleting the post, and then we traverse the database again, making sure that they have the author role on their profile. Otherwise, for admin users, we just need to make sure that they have the admin role on their profile, and they can create, update, or delete any data that they want. That's it for role based access control at Firebase. If this video helped you, please like and subscribe. And if you want the full code, head over to angularfirebase.com. And if you want access to exclusive content as well as 1 on 1 project consulting, consider becoming an Angular Firebase pro. Thanks for watching, and I'll talk to you soon.
        