UPDATED VIDEO Jan 2019 👉 https://youtu.be/qP5zw7fjQgo

Learn how to authenticate users with Google login, Firestore, and AngularFire v5. We also build a router guard to protect your routes from unauthenticated users. https://angularfirebase.com/lessons/google-user-auth-with-firestore-custom-data/

Google Login: https://firebase.google.com/docs/auth/web/google-signin
Firestore: https://firebase.google.com/docs/firestore
2024-02-04T08:01:35.137Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
aaf34e5e-d071-4927-8fd5-521cf44a4f43
3bf8810497821f6a28297c651e84e512b8670ccb6b03c9ec63bab278420173d1
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Firebase makes user authentication incredibly easy to implement in Angular, but the one drawback is that it's not easy to implement custom data on the auth object itself.
In this episode, I'm going to show you how to implement an OAuth system from scratch using AngularFire version 5 and also save custom user data to the Firestore database.
In addition, we're going to set up a router guard that will prevent unauthorized users from accessing certain routes.
I recommend that you follow along with the source code on angularfirebase.com, and make sure to subscribe to the channel for a bunch of updates regarding Firestore in the near future.
To get started, the first thing you'll need is a Firebase account, and make sure you have the Google login provider enabled.
I'm also assuming that you have an existing Angular project with AngularFire installed.
If not, go to the AngularFire docs and follow the setup instructions for version 5.
The first thing I'm going to do is create a core module, which is used in Angular to handle global services within your app such as authentication.
The core module is technically optional, but it is considered a good practice.
Once you have it generated, add it to the import section of the app module.
Then we can jump over to the core module, and we'll add AngularFire auth and AngularFirestore.
I also have an auth service in here which we're going to generate in the next step.
The auth service is going to handle most of the heavy lifting.
When you generate it, make sure to use the m flag so it gets added to the core module automatically.
Inside of our service, we're going to import the Angular router as well as the AngularFire auth and Firestore services.
We're also gonna use the RxJS observable class and the switch map operator as you'll see here in just a second.
The nice thing about our service is we can define an interface with any custom data that we wanna add to it.
So here I'm going to add a user interface, and I'll just add a few default values here that come with the normal Firebase auth state.
And then I'll also add a custom attribute for favorite color, but you could add anything you want here.
Then the next thing we'll do is set a variable on the service that is typed to this user interface.
From there, we can add our dependencies to the constructor, which is auth, Firestore, and the router.
Then we want to define the user observable inside the structures, so any component can subscribe to it and be updated with new data in real time.
So first, we need the data from the default auth state from Firebase.
So we can get that by calling switch map.
That will give us the user credential which can be either the user data or null.
So if it is defined, then we'll go ahead and and return that data that we save in the Firestore database.
So we can do that by pointing AngularFirestore to the user document that is in the user's collection and has an ID equal to their user ID, and then we call value changes on it to get the observable.
And just so this makes a little more sense, let's look at how we have the database structured.
We have a root users collection, and then each document in that collection has an ID equal to the Firebase auth user ID.
This allows you to add custom data to your users and also query them using the Firestore query methods.
So switching back to the service, Now we just wanna return an observable of null if that user object is not defined.
So the end result here is we're using data from Firestore instead of the data returned from on Firebase Auth.
So the next thing we'll do here is create a method for the user to log in with Google.
And I'm gonna set this up in a way so you can easily reuse the code if you wanna multiple methods such as Twitter, GitHub, or Facebook.
We can do that by passing the provider to this OAuth login method, and that will call the sign in with pop up and return a promise.
But we also need to save the user's initial data in the database, so we'll set up a separate method for that as well.
And we only wanna call that once the user has successfully authenticated through Firebase.
So once the user has authenticated, we're going to have a user ID.
We can use that user ID to make a reference to the Firestore users collection and then a document under that user ID.
From there, I'm just going to transfer some data from the normal Firebase auth to Firestore, but this is where you have the option to set custom data if you want to.
You could even delay this process and have the user fill out a secondary form where they enter required additional fields to their user account.
To save the data, we just need to call user ref, set data, and we're good to go.
The service is ready to authenticate users.
We just need a component to make this possible on the front end.
I'm going to generate a component called user profile, and then we'll just need to inject the auth service into this component.
Make sure that it's public when you add it to the constructor so you can use it in the HTML.
We want to display different HTML based on whether or not the user is authenticated.
We can figure that out by using n g f with the user variable from our auth service and the async pipe.
If the user's authenticated, it emits their data from Firestore, but if not, it just emits null.
From there, we're going to set up 2 different templates based on the authenticated state.
The first one will call authenticated, the other one will call guest.
Based on that state it will replace this div with the templates that we defined below.
We can set those templates with ng template and then a hashtag followed by that template variable name.
In the guest template, I'll just show that the user's a guest and then I'll add a button that will trigger the Google login method from our service when clicked.
Inside the authenticated template, I'm just going to set the user as a template variable so we can use that data from the observable.
So we do that by calling auth user async and then as user which represents the template variable.
So then we can call user display name or user photo URL, or any other custom data that you have in Firestore.
So now let's go see this in action.
We click the connect to Google button here and that should bring up an OAuth window.
And then once we're authenticated, we'll see that our data is updated in Firestore.
Currently, I don't have the favorite color property set, but we'll go ahead and set that in Firestore and you'll see it has a real time connection with the user interface.
As soon as we click add, you'll see that the favorite color gets updated here on the left side on the user interface.
If we click log out, You can see the user session ends, but we still have that data here persisted in Firestore.
So that's very useful if you query public user profiles that get shown throughout your app.
So that's pretty cool, but there's just one more piece of information I wanna show you to round out your auth service.
And that's how to create a router guard to protect routes from unauthorized users.
So first, we'll generate the guard with the Angular CLI.
Inside the guard, we're going to import an RxJS observable class and the auth service that we just created and also a few other RxJS Operators.
From there we'll add the auth service to the constructor of the guard and we can just call the user observable that we had created in the auth service.
We can call take 1 to prevent any long running subscriptions, and then we'll map the user object down to a boolean.
So if the user's logged in, that should return true, and if not, it'll return false.
If it returns true, then the guard will pass and they'll be able to access the route.
But if false, it will console log access denied and then we'll have the router navigate them back to the login page.
So you can add this guard to the can activate array in any of your routes, and then if you try to access one of those routes not being logged in, you'll get access denied message here in the console.
But if we go ahead and log in, then you can see we have full access to the routes, and everything works as expected.
That's it for Firebase OAuth with Firestore.
If this video helped you, please like and subscribe.
And if you wanna build more advanced features, consider becoming a pro member at angularfirebase.com.
You'll get a free copy of my book as well as 1 on 1 project consulting.
Thanks for watching, and I'll see you next time.

Speaker 0: Firebase makes user authentication incredibly easy to implement in Angular, but the one drawback is that it's not easy to implement custom data on the auth object itself. In this episode, I'm going to show you how to implement an OAuth system from scratch using AngularFire version 5 and also save custom user data to the Firestore database. In addition, we're going to set up a router guard that will prevent unauthorized users from accessing certain routes. I recommend that you follow along with the source code on angularfirebase.com, and make sure to subscribe to the channel for a bunch of updates regarding Firestore in the near future. To get started, the first thing you'll need is a Firebase account, and make sure you have the Google login provider enabled.

I'm also assuming that you have an existing Angular project with AngularFire installed. If not, go to the AngularFire docs and follow the setup instructions for version 5. The first thing I'm going to do is create a core module, which is used in Angular to handle global services within your app such as authentication. The core module is technically optional, but it is considered a good practice. Once you have it generated, add it to the import section of the app module.

Then we can jump over to the core module, and we'll add AngularFire auth and AngularFirestore. I also have an auth service in here which we're going to generate in the next step. The auth service is going to handle most of the heavy lifting. When you generate it, make sure to use the m flag so it gets added to the core module automatically. Inside of our service, we're going to import the Angular router as well as the AngularFire auth and Firestore services.

We're also gonna use the RxJS observable class and the switch map operator as you'll see here in just a second. The nice thing about our service is we can define an interface with any custom data that we wanna add to it. So here I'm going to add a user interface, and I'll just add a few default values here that come with the normal Firebase auth state. And then I'll also add a custom attribute for favorite color, but you could add anything you want here. Then the next thing we'll do is set a variable on the service that is typed to this user interface.

From there, we can add our dependencies to the constructor, which is auth, Firestore, and the router. Then we want to define the user observable inside the structures, so any component can subscribe to it and be updated with new data in real time. So first, we need the data from the default auth state from Firebase. So we can get that by calling switch map. That will give us the user credential which can be either the user data or null.

So if it is defined, then we'll go ahead and and return that data that we save in the Firestore database. So we can do that by pointing AngularFirestore to the user document that is in the user's collection and has an ID equal to their user ID, and then we call value changes on it to get the observable. And just so this makes a little more sense, let's look at how we have the database structured. We have a root users collection, and then each document in that collection has an ID equal to the Firebase auth user ID. This allows you to add custom data to your users and also query them using the Firestore query methods.

So switching back to the service, Now we just wanna return an observable of null if that user object is not defined. So the end result here is we're using data from Firestore instead of the data returned from on Firebase Auth. So the next thing we'll do here is create a method for the user to log in with Google. And I'm gonna set this up in a way so you can easily reuse the code if you wanna multiple methods such as Twitter, GitHub, or Facebook. We can do that by passing the provider to this OAuth login method, and that will call the sign in with pop up and return a promise.

But we also need to save the user's initial data in the database, so we'll set up a separate method for that as well. And we only wanna call that once the user has successfully authenticated through Firebase. So once the user has authenticated, we're going to have a user ID. We can use that user ID to make a reference to the Firestore users collection and then a document under that user ID. From there, I'm just going to transfer some data from the normal Firebase auth to Firestore, but this is where you have the option to set custom data if you want to.

You could even delay this process and have the user fill out a secondary form where they enter required additional fields to their user account. To save the data, we just need to call user ref, set data, and we're good to go. The service is ready to authenticate users. We just need a component to make this possible on the front end. I'm going to generate a component called user profile, and then we'll just need to inject the auth service into this component.

Make sure that it's public when you add it to the constructor so you can use it in the HTML. We want to display different HTML based on whether or not the user is authenticated. We can figure that out by using n g f with the user variable from our auth service and the async pipe. If the user's authenticated, it emits their data from Firestore, but if not, it just emits null. From there, we're going to set up 2 different templates based on the authenticated state.

The first one will call authenticated, the other one will call guest. Based on that state it will replace this div with the templates that we defined below. We can set those templates with ng template and then a hashtag followed by that template variable name. In the guest template, I'll just show that the user's a guest and then I'll add a button that will trigger the Google login method from our service when clicked. Inside the authenticated template, I'm just going to set the user as a template variable so we can use that data from the observable.

So we do that by calling auth user async and then as user which represents the template variable. So then we can call user display name or user photo URL, or any other custom data that you have in Firestore. So now let's go see this in action. We click the connect to Google button here and that should bring up an OAuth window. And then once we're authenticated, we'll see that our data is updated in Firestore.

Currently, I don't have the favorite color property set, but we'll go ahead and set that in Firestore and you'll see it has a real time connection with the user interface. As soon as we click add, you'll see that the favorite color gets updated here on the left side on the user interface. If we click log out, You can see the user session ends, but we still have that data here persisted in Firestore. So that's very useful if you query public user profiles that get shown throughout your app. So that's pretty cool, but there's just one more piece of information I wanna show you to round out your auth service.

And that's how to create a router guard to protect routes from unauthorized users. So first, we'll generate the guard with the Angular CLI. Inside the guard, we're going to import an RxJS observable class and the auth service that we just created and also a few other RxJS Operators. From there we'll add the auth service to the constructor of the guard and we can just call the user observable that we had created in the auth service. We can call take 1 to prevent any long running subscriptions, and then we'll map the user object down to a boolean.

So if the user's logged in, that should return true, and if not, it'll return false. If it returns true, then the guard will pass and they'll be able to access the route. But if false, it will console log access denied and then we'll have the router navigate them back to the login page. So you can add this guard to the can activate array in any of your routes, and then if you try to access one of those routes not being logged in, you'll get access denied message here in the console. But if we go ahead and log in, then you can see we have full access to the routes, and everything works as expected.

That's it for Firebase OAuth with Firestore. If this video helped you, please like and subscribe. And if you wanna build more advanced features, consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
Firebase makes user authentication incredibly easy to implement in Angular, but the one drawback is that it's not easy to implement custom data on the auth object itself. In this episode, I'm going to show you how to implement an OAuth system from scratch using AngularFire version 5 and also save custom user data to the Firestore database. In addition, we're going to set up a router guard that will prevent unauthorized users from accessing certain routes. I recommend that you follow along with the source code on angularfirebase.com, and make sure to subscribe to the channel for a bunch of updates regarding Firestore in the near future. To get started, the first thing you'll need is a Firebase account, and make sure you have the Google login provider enabled. I'm also assuming that you have an existing Angular project with AngularFire installed. If not, go to the AngularFire docs and follow the setup instructions for version 5. The first thing I'm going to do is create a core module, which is used in Angular to handle global services within your app such as authentication.
The core module is technically optional, but it is considered a good practice. Once you have it generated, add it to the import section of the app module. Then we can jump over to the core module, and we'll add AngularFire auth and AngularFirestore. I also have an auth service in here which we're going to generate in the next step.
software
software development
The auth service is going to handle most of the heavy lifting. When you generate it, make sure to use the m flag so it gets added to the core module automatically. Inside of our service, we're going to import the Angular router as well as the AngularFire auth and Firestore services. We're also gonna use the RxJS observable class and the switch map operator as you'll see here in just a second. The nice thing about our service is we can define an interface with any custom data that we wanna add to it. So here I'm going to add a user interface, and I'll just add a few default values here that come with the normal Firebase auth state. And then I'll also add a custom attribute for favorite color, but you could add anything you want here. Then the next thing we'll do is set a variable on the service that is typed to this user interface. From there, we can add our dependencies to the constructor, which is auth, Firestore, and the router. Then we want to define the user observable inside the structures, so any component can subscribe to it and be updated with new data in real time. So first, we need the data from the default auth state from Firebase. So we can get that by calling switch map. That will give us the user credential which can be either the user data or null.
So if it is defined, then we'll go ahead and and return that data that we save in the Firestore database. So we can do that by pointing AngularFirestore to the user document that is in the user's collection and has an ID equal to their user ID, and then we call value changes on it to get the observable. And just so this makes a little more sense, let's look at how we have the database structured. We have a root users collection, and then each document in that collection has an ID equal to the Firebase auth user ID. This allows you to add custom data to your users and also query them using the Firestore query methods.
databases
data management
data
So switching back to the service, Now we just wanna return an observable of null if that user object is not defined.
So the end result here is we're using data from Firestore instead of the data returned from on Firebase Auth. So the next thing we'll do here is create a method for the user to log in with Google. And I'm gonna set this up in a way so you can easily reuse the code if you wanna multiple methods such as Twitter, GitHub, or Facebook.
google
websites
We can do that by passing the provider to this OAuth login method, and that will call the sign in with pop up and return a promise. But we also need to save the user's initial data in the database, so we'll set up a separate method for that as well. And we only wanna call that once the user has successfully authenticated through Firebase. So once the user has authenticated, we're going to have a user ID. We can use that user ID to make a reference to the Firestore users collection and then a document under that user ID. From there, I'm just going to transfer some data from the normal Firebase auth to Firestore, but this is where you have the option to set custom data if you want to. You could even delay this process and have the user fill out a secondary form where they enter required additional fields to their user account.
To save the data, we just need to call user ref, set data, and we're good to go. The service is ready to authenticate users. We just need a component to make this possible on the front end. I'm going to generate a component called user profile, and then we'll just need to inject the auth service into this component.
customer support
Make sure that it's public when you add it to the constructor so you can use it in the HTML. We want to display different HTML based on whether or not the user is authenticated. We can figure that out by using n g f with the user variable from our auth service and the async pipe. If the user's authenticated, it emits their data from Firestore, but if not, it just emits null. From there, we're going to set up 2 different templates based on the authenticated state. The first one will call authenticated, the other one will call guest. Based on that state it will replace this div with the templates that we defined below. We can set those templates with ng template and then a hashtag followed by that template variable name. In the guest template, I'll just show that the user's a guest and then I'll add a button that will trigger the Google login method from our service when clicked. Inside the authenticated template, I'm just going to set the user as a template variable so we can use that data from the observable. So we do that by calling auth user async and then as user which represents the template variable.
So then we can call user display name or user photo URL, or any other custom data that you have in Firestore. So now let's go see this in action. We click the connect to Google button here and that should bring up an OAuth window. And then once we're authenticated, we'll see that our data is updated in Firestore. Currently, I don't have the favorite color property set, but we'll go ahead and set that in Firestore and you'll see it has a real time connection with the user interface.
google
As soon as we click add, you'll see that the favorite color gets updated here on the left side on the user interface. If we click log out, You can see the user session ends, but we still have that data here persisted in Firestore.
So that's very useful if you query public user profiles that get shown throughout your app. So that's pretty cool, but there's just one more piece of information I wanna show you to round out your auth service. And that's how to create a router guard to protect routes from unauthorized users.
security
networking
So first, we'll generate the guard with the Angular CLI. Inside the guard, we're going to import an RxJS observable class and the auth service that we just created and also a few other RxJS Operators.
From there we'll add the auth service to the constructor of the guard and we can just call the user observable that we had created in the auth service. We can call take 1 to prevent any long running subscriptions, and then we'll map the user object down to a boolean.
security
So if the user's logged in, that should return true, and if not, it'll return false. If it returns true, then the guard will pass and they'll be able to access the route. But if false, it will console log access denied and then we'll have the router navigate them back to the login page. So you can add this guard to the can activate array in any of your routes, and then if you try to access one of those routes not being logged in, you'll get access denied message here in the console. But if we go ahead and log in, then you can see we have full access to the routes, and everything works as expected. That's it for Firebase OAuth with Firestore.
If this video helped you, please like and subscribe. And if you wanna build more advanced features, consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
youtube
Firebase makes user authentication incredibly easy to implement in Angular, but the one drawback is that it's not easy to implement custom data on the auth object itself. In this episode, I'm going to show you how to implement an OAuth system from scratch using AngularFire version 5 and also save custom user data to the Firestore database. In addition, we're going to set up a router guard that will prevent unauthorized users from accessing certain routes. I recommend that you follow along with the source code on angularfirebase.com, and make sure to subscribe to the channel for a bunch of updates regarding Firestore in the near future. To get started, the first thing you'll need is a Firebase account, and make sure you have the Google login provider enabled. I'm also assuming that you have an existing Angular project with AngularFire installed. If not, go to the AngularFire docs and follow the setup instructions for version 5. The first thing I'm going to do is create a core module, which is used in Angular to handle global services within your app such as authentication. The core module is technically optional, but it is considered a good practice. Once you have it generated, add it to the import section of the app module. Then we can jump over to the core module, and we'll add AngularFire auth and AngularFirestore. I also have an auth service in here which we're going to generate in the next step. The auth service is going to handle most of the heavy lifting. When you generate it, make sure to use the m flag so it gets added to the core module automatically. Inside of our service, we're going to import the Angular router as well as the AngularFire auth and Firestore services. We're also gonna use the RxJS observable class and the switch map operator as you'll see here in just a second. The nice thing about our service is we can define an interface with any custom data that we wanna add to it. So here I'm going to add a user interface, and I'll just add a few default values here that come with the normal Firebase auth state. And then I'll also add a custom attribute for favorite color, but you could add anything you want here. Then the next thing we'll do is set a variable on the service that is typed to this user interface. From there, we can add our dependencies to the constructor, which is auth, Firestore, and the router. Then we want to define the user observable inside the structures, so any component can subscribe to it and be updated with new data in real time. So first, we need the data from the default auth state from Firebase. So we can get that by calling switch map. That will give us the user credential which can be either the user data or null. So if it is defined, then we'll go ahead and and return that data that we save in the Firestore database. So we can do that by pointing AngularFirestore to the user document that is in the user's collection and has an ID equal to their user ID, and then we call value changes on it to get the observable. And just so this makes a little more sense, let's look at how we have the database structured. We have a root users collection, and then each document in that collection has an ID equal to the Firebase auth user ID. This allows you to add custom data to your users and also query them using the Firestore query methods. So switching back to the service, Now we just wanna return an observable of null if that user object is not defined. So the end result here is we're using data from Firestore instead of the data returned from on Firebase Auth. So the next thing we'll do here is create a method for the user to log in with Google. And I'm gonna set this up in a way so you can easily reuse the code if you wanna multiple methods such as Twitter, GitHub, or Facebook. We can do that by passing the provider to this OAuth login method, and that will call the sign in with pop up and return a promise. But we also need to save the user's initial data in the database, so we'll set up a separate method for that as well. And we only wanna call that once the user has successfully authenticated through Firebase. So once the user has authenticated, we're going to have a user ID. We can use that user ID to make a reference to the Firestore users collection and then a document under that user ID. From there, I'm just going to transfer some data from the normal Firebase auth to Firestore, but this is where you have the option to set custom data if you want to. You could even delay this process and have the user fill out a secondary form where they enter required additional fields to their user account. To save the data, we just need to call user ref, set data, and we're good to go. The service is ready to authenticate users. We just need a component to make this possible on the front end. I'm going to generate a component called user profile, and then we'll just need to inject the auth service into this component. Make sure that it's public when you add it to the constructor so you can use it in the HTML. We want to display different HTML based on whether or not the user is authenticated. We can figure that out by using n g f with the user variable from our auth service and the async pipe. If the user's authenticated, it emits their data from Firestore, but if not, it just emits null. From there, we're going to set up 2 different templates based on the authenticated state. The first one will call authenticated, the other one will call guest. Based on that state it will replace this div with the templates that we defined below. We can set those templates with ng template and then a hashtag followed by that template variable name. In the guest template, I'll just show that the user's a guest and then I'll add a button that will trigger the Google login method from our service when clicked. Inside the authenticated template, I'm just going to set the user as a template variable so we can use that data from the observable. So we do that by calling auth user async and then as user which represents the template variable. So then we can call user display name or user photo URL, or any other custom data that you have in Firestore. So now let's go see this in action. We click the connect to Google button here and that should bring up an OAuth window. And then once we're authenticated, we'll see that our data is updated in Firestore. Currently, I don't have the favorite color property set, but we'll go ahead and set that in Firestore and you'll see it has a real time connection with the user interface. As soon as we click add, you'll see that the favorite color gets updated here on the left side on the user interface. If we click log out, You can see the user session ends, but we still have that data here persisted in Firestore. So that's very useful if you query public user profiles that get shown throughout your app. So that's pretty cool, but there's just one more piece of information I wanna show you to round out your auth service. And that's how to create a router guard to protect routes from unauthorized users. So first, we'll generate the guard with the Angular CLI. Inside the guard, we're going to import an RxJS observable class and the auth service that we just created and also a few other RxJS Operators. From there we'll add the auth service to the constructor of the guard and we can just call the user observable that we had created in the auth service. We can call take 1 to prevent any long running subscriptions, and then we'll map the user object down to a boolean. So if the user's logged in, that should return true, and if not, it'll return false. If it returns true, then the guard will pass and they'll be able to access the route. But if false, it will console log access denied and then we'll have the router navigate them back to the login page. So you can add this guard to the can activate array in any of your routes, and then if you try to access one of those routes not being logged in, you'll get access denied message here in the console. But if we go ahead and log in, then you can see we have full access to the routes, and everything works as expected. That's it for Firebase OAuth with Firestore. If this video helped you, please like and subscribe. And if you wanna build more advanced features, consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
Firebase
firebase
makes
makes
user
user
authentication
authentication
incredibly
incredibly
easy
easy
to
to
implement
implement
in
in
Angular,
angular
but
but
the
the
one
one
drawback
drawback
is
is
that
that
it's
it's
not
not
easy
easy
to
to
implement
implement
custom
custom
data
data
on
on
the
the
auth
auth
object
object
itself.
itself
In
in
this
this
episode,
episode
I'm
i'm
going
going
to
to
show
show
you
you
how
how
to
to
implement
implement
an
an
OAuth
oauth
system
system
from
from
scratch
scratch
using
using
AngularFire
angularfire
version
version
5
5
and
and
also
also
save
save
custom
custom
user
user
data
data
to
to
the
the
Firestore
firestore
database.
database
In
in
addition,
addition
we're
we're
going
going
to
to
set
set
up
up
a
a
router
router
guard
guard
that
that
will
will
prevent
prevent
unauthorized
unauthorized
users
users
from
from
accessing
accessing
certain
certain
routes.
routes
I
i
recommend
recommend
that
that
you
you
follow
follow
along
along
with
with
the
the
source
source
code
code
on
on
angularfirebase.com,
angularfirebase.com
and
and
make
make
sure
sure
to
to
subscribe
subscribe
to
to
the
the
channel
channel
for
for
a
a
bunch
bunch
of
of
updates
updates
regarding
regarding
Firestore
firestore
in
in
the
the
near
near
future.
future
To
to
get
get
started,
started
the
the
first
first
thing
thing
you'll
you'll
need
need
is
is
a
a
Firebase
firebase
account,
account
and
and
make
make
sure
sure
you
you
have
have
the
the
Google
google
login
login
provider
provider
enabled.
enabled
I'm
i'm
also
also
assuming
assuming
that
that
you
you
have
have
an
an
existing
existing
Angular
angular
project
project
with
with
AngularFire
angularfire
installed.
installed
If
if
not,
not
go
go
to
to
the
the
AngularFire
angularfire
docs
docs
and
and
follow
follow
the
the
setup
setup
instructions
instructions
for
for
version
version
5.
5
The
the
first
first
thing
thing
I'm
i'm
going
going
to
to
do
do
is
is
create
create
a
a
core
core
module,
module
which
which
is
is
used
used
in
in
Angular
angular
to
to
handle
handle
global
global
services
services
within
within
your
your
app
app
such
such
as
as
authentication.
authentication
The
the
core
core
module
module
is
is
technically
technically
optional,
optional
but
but
it
it
is
is
considered
considered
a
a
good
good
practice.
practice
Once
once
you
you
have
have
it
it
generated,
generated
add
add
it
it
to
to
the
the
import
import
section
section
of
of
the
the
app
app
module.
module
Then
then
we
we
can
can
jump
jump
over
over
to
to
the
the
core
core
module,
module
and
and
we'll
we'll
add
add
AngularFire
angularfire
auth
auth
and
and
AngularFirestore.
angularfirestore
I
i
also
also
have
have
an
an
auth
auth
service
service
in
in
here
here
which
which
we're
we're
going
going
to
to
generate
generate
in
in
the
the
next
next
step.
step
The
the
auth
auth
service
service
is
is
going
going
to
to
handle
handle
most
most
of
of
the
the
heavy
heavy
lifting.
lifting
When
when
you
you
generate
generate
it,
it
make
make
sure
sure
to
to
use
use
the
the
m
m
flag
flag
so
so
it
it
gets
gets
added
added
to
to
the
the
core
core
module
module
automatically.
automatically
Inside
inside
of
of
our
our
service,
service
we're
we're
going
going
to
to
import
import
the
the
Angular
angular
router
router
as
as
well
well
as
as
the
the
AngularFire
angularfire
auth
auth
and
and
Firestore
firestore
services.
services
We're
we're
also
also
gonna
gonna
use
use
the
the
RxJS
rxjs
observable
observable
class
class
and
and
the
the
switch
switch
map
map
operator
operator
as
as
you'll
you'll
see
see
here
here
in
in
just
just
a
a
second.
second
The
the
nice
nice
thing
thing
about
about
our
our
service
service
is
is
we
we
can
can
define
define
an
an
interface
interface
with
with
any
any
custom
custom
data
data
that
that
we
we
wanna
wanna
add
add
to
to
it.
it
So
so
here
here
I'm
i'm
going
going
to
to
add
add
a
a
user
user
interface,
interface
and
and
I'll
i'll
just
just
add
add
a
a
few
few
default
default
values
values
here
here
that
that
come
come
with
with
the
the
normal
normal
Firebase
firebase
auth
auth
state.
state
And
and
then
then
I'll
i'll
also
also
add
add
a
a
custom
custom
attribute
attribute
for
for
favorite
favorite
color,
color
but
but
you
you
could
could
add
add
anything
anything
you
you
want
want
here.
here
Then
then
the
the
next
next
thing
thing
we'll
we'll
do
do
is
is
set
set
a
a
variable
variable
on
on
the
the
service
service
that
that
is
is
typed
typed
to
to
this
this
user
user
interface.
interface
From
from
there,
there
we
we
can
can
add
add
our
our
dependencies
dependencies
to
to
the
the
constructor,
constructor
which
which
is
is
auth,
auth
Firestore,
firestore
and
and
the
the
router.
router
Then
then
we
we
want
want
to
to
define
define
the
the
user
user
observable
observable
inside
inside
the
the
structures,
structures
so
so
any
any
component
component
can
can
subscribe
subscribe
to
to
it
it
and
and
be
be
updated
updated
with
with
new
new
data
data
in
in
real
real
time.
time
So
so
first,
first
we
we
need
need
the
the
data
data
from
from
the
the
default
default
auth
auth
state
state
from
from
Firebase.
firebase
So
so
we
we
can
can
get
get
that
that
by
by
calling
calling
switch
switch
map.
map
That
that
will
will
give
give
us
us
the
the
user
user
credential
credential
which
which
can
can
be
be
either
either
the
the
user
user
data
data
or
or
null.
null
So
so
if
if
it
it
is
is
defined,
defined
then
then
we'll
we'll
go
go
ahead
ahead
and
and
and
and
return
return
that
that
data
data
that
that
we
we
save
save
in
in
the
the
Firestore
firestore
database.
database
So
so
we
we
can
can
do
do
that
that
by
by
pointing
pointing
AngularFirestore
angularfirestore
to
to
the
the
user
user
document
document
that
that
is
is
in
in
the
the
user's
user's
collection
collection
and
and
has
has
an
an
ID
id
equal
equal
to
to
their
their
user
user
ID,
id
and
and
then
then
we
we
call
call
value
value
changes
changes
on
on
it
it
to
to
get
get
the
the
observable.
observable
And
and
just
just
so
so
this
this
makes
makes
a
a
little
little
more
more
sense,
sense
let's
let's
look
look
at
at
how
how
we
we
have
have
the
the
database
database
structured.
structured
We
we
have
have
a
a
root
root
users
users
collection,
collection
and
and
then
then
each
each
document
document
in
in
that
that
collection
collection
has
has
an
an
ID
id
equal
equal
to
to
the
the
Firebase
firebase
auth
auth
user
user
ID.
id
This
this
allows
allows
you
you
to
to
add
add
custom
custom
data
data
to
to
your
your
users
users
and
and
also
also
query
query
them
them
using
using
the
the
Firestore
firestore
query
query
methods.
methods
So
so
switching
switching
back
back
to
to
the
the
service,
service
Now
now
we
we
just
just
wanna
wanna
return
return
an
an
observable
observable
of
of
null
null
if
if
that
that
user
user
object
object
is
is
not
not
defined.
defined
So
so
the
the
end
end
result
result
here
here
is
is
we're
we're
using
using
data
data
from
from
Firestore
firestore
instead
instead
of
of
the
the
data
data
returned
returned
from
from
on
on
Firebase
firebase
Auth.
auth
So
so
the
the
next
next
thing
thing
we'll
we'll
do
do
here
here
is
is
create
create
a
a
method
method
for
for
the
the
user
user
to
to
log
log
in
in
with
with
Google.
google
And
and
I'm
i'm
gonna
gonna
set
set
this
this
up
up
in
in
a
a
way
way
so
so
you
you
can
can
easily
easily
reuse
reuse
the
the
code
code
if
if
you
you
wanna
wanna
multiple
multiple
methods
methods
such
such
as
as
Twitter,
twitter
GitHub,
github
or
or
Facebook.
facebook
We
we
can
can
do
do
that
that
by
by
passing
passing
the
the
provider
provider
to
to
this
this
OAuth
oauth
login
login
method,
method
and
and
that
that
will
will
call
call
the
the
sign
sign
in
in
with
with
pop
pop
up
up
and
and
return
return
a
a
promise.
promise
But
but
we
we
also
also
need
need
to
to
save
save
the
the
user's
user's
initial
initial
data
data
in
in
the
the
database,
database
so
so
we'll
we'll
set
set
up
up
a
a
separate
separate
method
method
for
for
that
that
as
as
well.
well
And
and
we
we
only
only
wanna
wanna
call
call
that
that
once
once
the
the
user
user
has
has
successfully
successfully
authenticated
authenticated
through
through
Firebase.
firebase
So
so
once
once
the
the
user
user
has
has
authenticated,
authenticated
we're
we're
going
going
to
to
have
have
a
a
user
user
ID.
id
We
we
can
can
use
use
that
that
user
user
ID
id
to
to
make
make
a
a
reference
reference
to
to
the
the
Firestore
firestore
users
users
collection
collection
and
and
then
then
a
a
document
document
under
under
that
that
user
user
ID.
id
From
from
there,
there
I'm
i'm
just
just
going
going
to
to
transfer
transfer
some
some
data
data
from
from
the
the
normal
normal
Firebase
firebase
auth
auth
to
to
Firestore,
firestore
but
but
this
this
is
is
where
where
you
you
have
have
the
the
option
option
to
to
set
set
custom
custom
data
data
if
if
you
you
want
want
to.
to
You
you
could
could
even
even
delay
delay
this
this
process
process
and
and
have
have
the
the
user
user
fill
fill
out
out
a
a
secondary
secondary
form
form
where
where
they
they
enter
enter
required
required
additional
additional
fields
fields
to
to
their
their
user
user
account.
account
To
to
save
save
the
the
data,
data
we
we
just
just
need
need
to
to
call
call
user
user
ref,
ref
set
set
data,
data
and
and
we're
we're
good
good
to
to
go.
go
The
the
service
service
is
is
ready
ready
to
to
authenticate
authenticate
users.
users
We
we
just
just
need
need
a
a
component
component
to
to
make
make
this
this
possible
possible
on
on
the
the
front
front
end.
end
I'm
i'm
going
going
to
to
generate
generate
a
a
component
component
called
called
user
user
profile,
profile
and
and
then
then
we'll
we'll
just
just
need
need
to
to
inject
inject
the
the
auth
auth
service
service
into
into
this
this
component.
component
Make
make
sure
sure
that
that
it's
it's
public
public
when
when
you
you
add
add
it
it
to
to
the
the
constructor
constructor
so
so
you
you
can
can
use
use
it
it
in
in
the
the
HTML.
html
We
we
want
want
to
to
display
display
different
different
HTML
html
based
based
on
on
whether
whether
or
or
not
not
the
the
user
user
is
is
authenticated.
authenticated
We
we
can
can
figure
figure
that
that
out
out
by
by
using
using
n
n
g
g
f
f
with
with
the
the
user
user
variable
variable
from
from
our
our
auth
auth
service
service
and
and
the
the
async
async
pipe.
pipe
If
if
the
the
user's
user's
authenticated,
authenticated
it
it
emits
emits
their
their
data
data
from
from
Firestore,
firestore
but
but
if
if
not,
not
it
it
just
just
emits
emits
null.
null
From
from
there,
there
we're
we're
going
going
to
to
set
set
up
up
2
2
different
different
templates
templates
based
based
on
on
the
the
authenticated
authenticated
state.
state
The
the
first
first
one
one
will
will
call
call
authenticated,
authenticated
the
the
other
other
one
one
will
will
call
call
guest.
guest
Based
based
on
on
that
that
state
state
it
it
will
will
replace
replace
this
this
div
div
with
with
the
the
templates
templates
that
that
we
we
defined
defined
below.
below
We
we
can
can
set
set
those
those
templates
templates
with
with
ng
ng
template
template
and
and
then
then
a
a
hashtag
hashtag
followed
followed
by
by
that
that
template
template
variable
variable
name.
name
In
in
the
the
guest
guest
template,
template
I'll
i'll
just
just
show
show
that
that
the
the
user's
user's
a
a
guest
guest
and
and
then
then
I'll
i'll
add
add
a
a
button
button
that
that
will
will
trigger
trigger
the
the
Google
google
login
login
method
method
from
from
our
our
service
service
when
when
clicked.
clicked
Inside
inside
the
the
authenticated
authenticated
template,
template
I'm
i'm
just
just
going
going
to
to
set
set
the
the
user
user
as
as
a
a
template
template
variable
variable
so
so
we
we
can
can
use
use
that
that
data
data
from
from
the
the
observable.
observable
So
so
we
we
do
do
that
that
by
by
calling
calling
auth
auth
user
user
async
async
and
and
then
then
as
as
user
user
which
which
represents
represents
the
the
template
template
variable.
variable
So
so
then
then
we
we
can
can
call
call
user
user
display
display
name
name
or
or
user
user
photo
photo
URL,
url
or
or
any
any
other
other
custom
custom
data
data
that
that
you
you
have
have
in
in
Firestore.
firestore
So
so
now
now
let's
let's
go
go
see
see
this
this
in
in
action.
action
We
we
click
click
the
the
connect
connect
to
to
Google
google
button
button
here
here
and
and
that
that
should
should
bring
bring
up
up
an
an
OAuth
oauth
window.
window
And
and
then
then
once
once
we're
we're
authenticated,
authenticated
we'll
we'll
see
see
that
that
our
our
data
data
is
is
updated
updated
in
in
Firestore.
firestore
Currently,
currently
I
i
don't
don't
have
have
the
the
favorite
favorite
color
color
property
property
set,
set
but
but
we'll
we'll
go
go
ahead
ahead
and
and
set
set
that
that
in
in
Firestore
firestore
and
and
you'll
you'll
see
see
it
it
has
has
a
a
real
real
time
time
connection
connection
with
with
the
the
user
user
interface.
interface
As
as
soon
soon
as
as
we
we
click
click
add,
add
you'll
you'll
see
see
that
that
the
the
favorite
favorite
color
color
gets
gets
updated
updated
here
here
on
on
the
the
left
left
side
side
on
on
the
the
user
user
interface.
interface
If
if
we
we
click
click
log
log
out,
out
You
you
can
can
see
see
the
the
user
user
session
session
ends,
ends
but
but
we
we
still
still
have
have
that
that
data
data
here
here
persisted
persisted
in
in
Firestore.
firestore
So
so
that's
that's
very
very
useful
useful
if
if
you
you
query
query
public
public
user
user
profiles
profiles
that
that
get
get
shown
shown
throughout
throughout
your
your
app.
app
So
so
that's
that's
pretty
pretty
cool,
cool
but
but
there's
there's
just
just
one
one
more
more
piece
piece
of
of
information
information
I
i
wanna
wanna
show
show
you
you
to
to
round
round
out
out
your
your
auth
auth
service.
service
And
and
that's
that's
how
how
to
to
create
create
a
a
router
router
guard
guard
to
to
protect
protect
routes
routes
from
from
unauthorized
unauthorized
users.
users
So
so
first,
first
we'll
we'll
generate
generate
the
the
guard
guard
with
with
the
the
Angular
angular
CLI.
cli
Inside
inside
the
the
guard,
guard
we're
we're
going
going
to
to
import
import
an
an
RxJS
rxjs
observable
observable
class
class
and
and
the
the
auth
auth
service
service
that
that
we
we
just
just
created
created
and
and
also
also
a
a
few
few
other
other
RxJS
rxjs
Operators.
operators
From
from
there
there
we'll
we'll
add
add
the
the
auth
auth
service
service
to
to
the
the
constructor
constructor
of
of
the
the
guard
guard
and
and
we
we
can
can
just
just
call
call
the
the
user
user
observable
observable
that
that
we
we
had
had
created
created
in
in
the
the
auth
auth
service.
service
We
we
can
can
call
call
take
take
1
1
to
to
prevent
prevent
any
any
long
long
running
running
subscriptions,
subscriptions
and
and
then
then
we'll
we'll
map
map
the
the
user
user
object
object
down
down
to
to
a
a
boolean.
boolean
So
so
if
if
the
the
user's
user's
logged
logged
in,
in
that
that
should
should
return
return
true,
true
and
and
if
if
not,
not
it'll
it'll
return
return
false.
false
If
if
it
it
returns
returns
true,
true
then
then
the
the
guard
guard
will
will
pass
pass
and
and
they'll
they'll
be
be
able
able
to
to
access
access
the
the
route.
route
But
but
if
if
false,
false
it
it
will
will
console
console
log
log
access
access
denied
denied
and
and
then
then
we'll
we'll
have
have
the
the
router
router
navigate
navigate
them
them
back
back
to
to
the
the
login
login
page.
page
So
so
you
you
can
can
add
add
this
this
guard
guard
to
to
the
the
can
can
activate
activate
array
array
in
in
any
any
of
of
your
your
routes,
routes
and
and
then
then
if
if
you
you
try
try
to
to
access
access
one
one
of
of
those
those
routes
routes
not
not
being
being
logged
logged
in,
in
you'll
you'll
get
get
access
access
denied
denied
message
message
here
here
in
in
the
the
console.
console
But
but
if
if
we
we
go
go
ahead
ahead
and
and
log
log
in,
in
then
then
you
you
can
can
see
see
we
we
have
have
full
full
access
access
to
to
the
the
routes,
routes
and
and
everything
everything
works
works
as
as
expected.
expected
That's
that's
it
it
for
for
Firebase
firebase
OAuth
oauth
with
with
Firestore.
firestore
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
wanna
wanna
build
build
more
more
advanced
advanced
features,
features
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
a
a
free
free
copy
copy
of
of
my
my
book
book
as
as
well
well
as
as
1
1
on
on
1
1
project
project
consulting.
consulting
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
see
see
you
you
next
next
time.
time
success
The speakers discuss implementing a custom data implementation in Angular, creating a denies account and router guard, and setting a variable for a user interface. They also explain how to set up a user profile and create a new one, and how to use the face ID in the Foveract service to authenticate users and change the default authenticator. They also show how to set up a router guard and access routes not logged in, and offer a free book and a project consulting link.
Google Sign-In with Firestore Custom User Data
Firebase makes user authentication incredibly easy to implement in Angular, but the one drawback is that it's not easy to implement custom data on the auth object itself. In this episode, I'm going to show you how to implement an OAuth system from scratch using AngularFire version 5 and also save custom user data to the Firestore database. In addition, we're going to set up a router guard that will prevent unauthorized users from accessing certain routes. I recommend that you follow along with the source code on angularfirebase.com, and make sure to subscribe to the channel for a bunch of updates regarding Firestore in the near future. To get started, the first thing you'll need is a Firebase account, and make sure you have the Google login provider enabled. I'm also assuming that you have an existing Angular project with AngularFire installed. If not, go to the AngularFire docs and follow the setup instructions for version 5. The first thing I'm going to do is create a core module, which is used in Angular to handle global services within your app such as authentication. The core module is technically optional, but it is considered a good practice. Once you have it generated, add it to the import section of the app module. Then we can jump over to the core module, and we'll add AngularFire auth and AngularFirestore. I also have an auth service in here which we're going to generate in the next step. The auth service is going to handle most of the heavy lifting. When you generate it, make sure to use the m flag so it gets added to the core module automatically. Inside of our service, we're going to import the Angular router as well as the AngularFire auth and Firestore services. We're also gonna use the RxJS observable class and the switch map operator as you'll see here in just a second. The nice thing about our service is we can define an interface with any custom data that we wanna add to it. So here I'm going to add a user interface, and I'll just add a few default values here that come with the normal Firebase auth state. And then I'll also add a custom attribute for favorite color, but you could add anything you want here. Then the next thing we'll do is set a variable on the service that is typed to this user interface. From there, we can add our dependencies to the constructor, which is auth, Firestore, and the router. Then we want to define the user observable inside the structures, so any component can subscribe to it and be updated with new data in real time. So first, we need the data from the default auth state from Firebase. So we can get that by calling switch map. That will give us the user credential which can be either the user data or null. So if it is defined, then we'll go ahead and and return that data that we save in the Firestore database. So we can do that by pointing AngularFirestore to the user document that is in the user's collection and has an ID equal to their user ID, and then we call value changes on it to get the observable. And just so this makes a little more sense, let's look at how we have the database structured. We have a root users collection, and then each document in that collection has an ID equal to the Firebase auth user ID. This allows you to add custom data to your users and also query them using the Firestore query methods. So switching back to the service, Now we just wanna return an observable of null if that user object is not defined. So the end result here is we're using data from Firestore instead of the data returned from on Firebase Auth. So the next thing we'll do here is create a method for the user to log in with Google. And I'm gonna set this up in a way so you can easily reuse the code if you wanna multiple methods such as Twitter, GitHub, or Facebook. We can do that by passing the provider to this OAuth login method, and that will call the sign in with pop up and return a promise. But we also need to save the user's initial data in the database, so we'll set up a separate method for that as well. And we only wanna call that once the user has successfully authenticated through Firebase. So once the user has authenticated, we're going to have a user ID. We can use that user ID to make a reference to the Firestore users collection and then a document under that user ID. From there, I'm just going to transfer some data from the normal Firebase auth to Firestore, but this is where you have the option to set custom data if you want to. You could even delay this process and have the user fill out a secondary form where they enter required additional fields to their user account. To save the data, we just need to call user ref, set data, and we're good to go. The service is ready to authenticate users. We just need a component to make this possible on the front end. I'm going to generate a component called user profile, and then we'll just need to inject the auth service into this component. Make sure that it's public when you add it to the constructor so you can use it in the HTML. We want to display different HTML based on whether or not the user is authenticated. We can figure that out by using n g f with the user variable from our auth service and the async pipe. If the user's authenticated, it emits their data from Firestore, but if not, it just emits null. From there, we're going to set up 2 different templates based on the authenticated state. The first one will call authenticated, the other one will call guest. Based on that state it will replace this div with the templates that we defined below. We can set those templates with ng template and then a hashtag followed by that template variable name. In the guest template, I'll just show that the user's a guest and then I'll add a button that will trigger the Google login method from our service when clicked. Inside the authenticated template, I'm just going to set the user as a template variable so we can use that data from the observable. So we do that by calling auth user async and then as user which represents the template variable. So then we can call user display name or user photo URL, or any other custom data that you have in Firestore. So now let's go see this in action. We click the connect to Google button here and that should bring up an OAuth window. And then once we're authenticated, we'll see that our data is updated in Firestore. Currently, I don't have the favorite color property set, but we'll go ahead and set that in Firestore and you'll see it has a real time connection with the user interface. As soon as we click add, you'll see that the favorite color gets updated here on the left side on the user interface. If we click log out, You can see the user session ends, but we still have that data here persisted in Firestore. So that's very useful if you query public user profiles that get shown throughout your app. So that's pretty cool, but there's just one more piece of information I wanna show you to round out your auth service. And that's how to create a router guard to protect routes from unauthorized users. So first, we'll generate the guard with the Angular CLI. Inside the guard, we're going to import an RxJS observable class and the auth service that we just created and also a few other RxJS Operators. From there we'll add the auth service to the constructor of the guard and we can just call the user observable that we had created in the auth service. We can call take 1 to prevent any long running subscriptions, and then we'll map the user object down to a boolean. So if the user's logged in, that should return true, and if not, it'll return false. If it returns true, then the guard will pass and they'll be able to access the route. But if false, it will console log access denied and then we'll have the router navigate them back to the login page. So you can add this guard to the can activate array in any of your routes, and then if you try to access one of those routes not being logged in, you'll get access denied message here in the console. But if we go ahead and log in, then you can see we have full access to the routes, and everything works as expected. That's it for Firebase OAuth with Firestore. If this video helped you, please like and subscribe. And if you wanna build more advanced features, consider becoming a pro member at angularfirebase.com. You'll get a free copy of my book as well as 1 on 1 project consulting. Thanks for watching, and I'll see you next time.
The speakers discuss implementing a custom data implementation in Angular, creating a denies account and router guard, and setting a variable for a user interface. They also explain how to set up a user profile and create a new one, and how to use the face ID in the Foveract service to authenticate users and change the default authenticator. They also show how to set up a router guard and access routes not logged in, and offer a free book and a project consulting link.