Angular Firebase Chat Tutorial - Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] [Music] all right welcome back to the second part of our angular firebase chat application when we left off in the previous video we had just completed creating a basic version of our message component and on our page we were able to show that we can post messages to firebase and then of course display them on the page so that's obviously really important functionality for our application and so what I'd like to do now is to start applying some of our styling and though the focus of this series of videos isn't really on CSS I will go through the CSS files here that we're about to create just to show you sort of my line of thinking all right so I'm going to minimize this and before we do that I'm going to remove what we have in our existing message container and replace it with the actual markup that we'll be using in the initial version of this app so the first thing that I'll do is I'll have a div that'll represent the left side of our chat bar and that's going to contain our message sender so the display name for the user who sends a message and then the timestamp so let's just call that message data I guess just for a lack of a better name and then we're going to have two spans so the first stand that will have will be for our sender and this is going to contain the username that's on our component and then the next span is going to contain a timestamp and here if you recall we're actually passing our component a date object so we can use a date pipe here and just specify the format using a built in angular pipe and in this case we will use the medium date format okay so that's the left side of our message then for the right side of our message that's going to be where the actual message body is contained and so that's just our message content okay so that will be the initial version of our message container here once we add authentication later in this video we'll come back here and look at how we can dynamically change the styling on each of these elements here so that if I for example a user send a message it's a different color than if another user in the chatroom sends a message but for now this will handle the basic layout of our message component so let's quickly take a look at our page and everything is still rendering more or less properly and yeah so we have the username we have this new date format that we're using an angular pipe for and we've got our messages that are coming out to the screen as well so let's go ahead and start doing something about the styling here so the first place I'm going to actually head into is the global style of that CSS file so this is our and our style sheet where we can apply global stylings so I think we defined here will be defined across our entire application so now I'm going to go ahead and paste in these global styles and full disclosure I'm definitely not a CSS expert by any stretch of the imagination and so as we go through this you may identify areas where you do things differently and certainly I probably would too if I went through this and revised it a second time so maybe we'll save that as something to do towards the end of this series but my goal here is just to get it to a presentable state and having it look nice and easy to work with which it will be there also may be places where we could do things a little bit more cleanly as well so in any case with that small disclaimer I'll just quickly go through what we have here in the global styles so I'm going to by default set all the elements height to 100% and use this box sizing border box so setting the box sizing to border box is a nice go to work if you're building a template up from scratch because it allows us to more intuitively set the size of our Dom elements so say when we set the width of an element by default CSS is probably going to use content box and so that won't include the padding and border of that element when we set it and so instead when we set the box sizing to border box when we specify the width or the height on that element it's also going to include its border and pad values alright so then we've got the body tag here with some pretty standard stuff I had the background Tashman fixed here because it initially had a background URL here alright so for our first element selector here we have one of our angular components so for our chat room notice that I'm standing display here equal to flex so we'll be using CSS flexbox extensively throughout this application I think it makes for a really nice intuitive way to design and build layouts and then we're going to set the Flex Direction on that component to column as opposed to row and we can look at how that would change the look of our application if we play route that a little bit later now to make more sense once we have all of our components set up and we get a we get a sense for how everything's laid out so then I'm going to have the nav bar component and the chat form both with 100% width and the chat form will have a flex display and that's because I want the search bar and the button to take up the full width of the chat form component and have their individual size and defined relative to each other and then we've got a message component here which we're going to set to display block so this is probably redundant if this message class is set on divs but in any case that should work and then we'll just set height to auto all right so I'm going to go ahead and save that and so now let's head over into our app component CSS file alright I'm going to go ahead and paste what I have here alright so we have our chat header wrapper class I'm going to set an explicit height there we give it a bit of a box shadow here and set it Z index value to two and so that way it will be on top of some of the other elements in our Dom okay then we have our chatroom class and so I'm setting probably a redundant height of 100% here and then we're setting the display to flex and the Flex direction to column and so we'll be applying flex dialing to all of the child elements of chat Road and then I have a router outlet element selector here and I'm just setting the height on that to zero so this is because the router outlet will actually get rendered to the Dom and I don't want it interfering with anything else that I have going on in the and so we're just going to make a tight zero to avoid any of those sort of complications so we'll head up here into chat room components ESS and I'm going to go ahead and paste this in as well if we go to the top so I'm setting a flex display on the main content class and then also on the user list wrapper and using a google font here and in a moment we'll go ahead and use the google fonts CDN to bring this font into use in our application and so yeah some basic stuff here we're setting the Flex value here to one so this is essentially setting the Flex grow property to one and some other fairly standard stuff here I'm going to move the color up here so this is setting the font color and then the order property here is again four flex box telling us what order this component appears relative to its sibling components and then yeah setting a background color here again I'm going to move this up and then some padding and a border on the right okay so that our feed wrapper this contains our feed component also setting the font here and making the font size a little bit larger and setting a Flex grow value of five here and then we specify it as being second in order inside of its container and then I'm setting the overflow Y here to scroll and so what this is going to do is it's going to create a scrollbar on that div such that when text overflows the div we can continue reading it by scrolling through it who were to set it to auto that would also work I think where the overflow would then generate a scrollbar once it's extended the size of the div any case we're going to just set it to scroll by default and then yeah so then we have a background color and then I have this linear gradient that I'm applying over an image and so you can see that I'm specifying a relative path to an image directory here in our assets folder so let's go ahead and create that so if we look over inside our source directory you should have a directory called assets so just go ahead and create a new folder in assets and I named it IMG and then I'm just going to drop some images in there that I'd like to use as background images for various parts of this application so I'm just going to go ahead and drop those here feel free to find any images you'd like to use here and replace them and also play around with you know this linear gradient maybe you don't even prefer to use it at all just to add kind of interesting effect on the images that I'm using here okay and some other basic stuff here that we've covered then I've got the chat form wrapper and then this scroll style defined here as well and so this is just going to be used to customize the scroll bar that's used in our feed and we'll look at that in a little while now let's head over into our chat form component so I'm going to go ahead and paste the CSS here and some pretty basic styling going on here as well so I'm going to set a rather large flex Gro value for the chat input which will be a sibling component to our chat button div and so the flux value on that will be one while a flex grow value of 10 on our chat input a bit of transition for when we focus on the chat input as well as when we hover on the chat button okay so pretty straightforward there so let's go ahead and take a look at our feet which should be here and our feeds going to be really simple so just have a feed class with a display flex and Direction column and then a message class with Direction column and a little bit of margin and so this will apply a margin in between each of our chat messages which just kind of keeps things looking nice and tidy all right so let's take a look at our application so far all right so it's starting to come together a little bit and see we have our messages here in the sort of feed area and the nav bar is starting to look more like a nav bar and you can see over here where we will eventually have the user list it looks like the next thing we should probably do is go ahead and style our messages here so if we head into the message component CSS okay so I'm going to go ahead and paste in the CSS for our message component here okay so first we have our message container class and I have a Flex display on that and then the width of our message container will be 70% notice also that I'm setting the height here to auto and that way the height of each message container will just be determined by the amount of text inside of it and then notice I have this class is own message container so this will be the class that we will dynamically applied to message containers that are sent by the current authenticated user so the user that's actually sending the messages will have some unique styling applied to their message as opposed to the normal message containers which will just be on all the other messages in the chat and so we'll change the background color to this blue color but I have a message data class here that's just going to actually contain the sender in the time stamp and so the sender class is just used to apply a color to the text and a bold font weight and then when it is the user's own message being sent then the background on that div will be darker and so will have a lighter font color for it likewise on the time stamp specifying a custom color when it is own time stamp and then finally we have our message content again just some basic styling applying a little bit of border radius on the top right and the bottom right of this message box setting a flex grow of nine here with an auto height and then when it is our own messages being sent will have blue text with a very light blue background here so I'm going to scroll up here alright cool so let's actually go back into our message component here and go ahead and add this last class that we need here on this div for our message content which is also just message content and now let's go ahead and take a quick look at our page and see what it looks like all right so we're getting much more reasonable results here also notice that if you type in enough messages to have overflow in your feed here you should also be able to scroll so that's looking pretty good okay so the next thing I think that we should do here is to set up authentication for our application so if you recall in the previous video we set our sign-in method to email and password I've had some requests also to take a look at authentication using Google and Facebook and some of the other social auth options and the angularfire package makes it extremely easy to actually authenticate using any of these methods so that'll be something that I'd like we'll get in a future video but just to get our application working here we'll start with email and password and then yeah we can implement some of these other options once their application is working so let's go ahead and create our sign up and login forms very quickly so that we can actually register some new users here and once we do that we'll be able to see them here in our users list so we could add them from the console but since we want to be able to register from our application anyway let's just go ahead and take care of that now so I'm going to minimize this and then we're going to head over into our signup component so let's check out signup form component TS and we're going to make another couple imports here so import router from a dangler slash router and just going to fix this typo here and then we're also going to import our authentication service and that's going to be one directory up in our services directory slash off that service ok so we're going to export our signup form component and we'll use four different properties on this component so first of all we'll have an email if the user will provide we'll have a password which will also just stores a string and then we'll have a display name as a string and an error message that we can use in case there's some type of error while signing out we can use this to display on the front end of the user and then in our constructor here I'm just going to go ahead and inject an all-service instance here and an instance of our router as well and I'm not going to worry about doing anything on an it here so we can also just remove that and we can remove this method and this component is just simply going to have one and go ahead and also go ahead and fix this typo and I'll go ahead and get rid of this white space here alright so we're just going to have a single method here on this component which will just be signup and of course we'll be using our authentication service in order to handle actually signing up and registering the new user with firebase all that our signup method here in the component is essentially a thin wrapper around a sign-up method that will exist in our authentication service and we'll use it just to pass the params that the user passes in on a form on this component so we'll have an email value equal to this email and we're going to data bind that to a value that's coming in from the signup form same with the password and then we'll have a display name and so we're going to invoke the authentication service here and we'll use a sign up message audit and so this is going to return a promise we're going to pass it the email password and display name to use and so when that promise is resolved we'll say then we're just going to use the router to navigate to the chatroom so that way when a user first signs up they just get redirected directly over to the chat and then in fact we can also say that catch in case anything erroneous happens during the signup process we can set the error message equal to the message that gets returned here that occurs okay and so clearly we need to go ahead and write a signup method on our authentication service that we can use and so we'll just need the email password and display name in order to set that up so let's go ahead and head over to our authentication service class and create this signup method so I'll head over to all service PS and I'll go ahead and make our imports here so we'll import router will import angularfire off will import angularfire database also going to import vanilla firebase here as well then we're going to need to import observable again from rxjs and then our custom user model which is one directory up in our models directory and then it's at user dot model okay so this is a service so it will be injectable of course and we are going to have a private user on this class here which will be an observable firebase user so firebase dot user here and then we'll have a private off state which I'll just set to any for right now but this off state will be observable that we'll use to determine the authentication state of the current user and so it will have a user ID on it that we can use to verify whether or not users logged in they'll have a constructor here for the service and which will inject our angularfire off instance our angularfire database and our router and i'm going to go ahead and clean this up a little bit and go ahead and delete the duplicate constructor here and then instead of our constructor I'm just going to set this user equal to the off state here so let's go ahead and write our signup method and if you recall we need to pass that an email password and our users chosen display name and what we're going to return is an observable here using angular fire authentication and so we'll say this AFL off we have this all property on it we have a method here we have a lot of different methods here but what we're going to do is create user with email and password and for this we just passed email and password that we've passed our method yeah I said this was an observable I believe itself a promise and so we say then and then we'll have an arrow expression here such that we want to set our auth state now based on the return from this promise so I'll set this dot all state to user okay and before we get any further agree I'm also going to write a catch here for any errors that occur and we'll just log them to the console right now okay so when we sign up with our email and password I do want to set the off state here in our promise and catch any errors and for now just love them out to the console but what I'd also like to do is to also store the user's display name email and their current status like whether or not they're online or not in a live database so for example at the time of this video I'm not aware of any way for instance to get all the users from firebase authentication side of things and so the way that I've decided to handle it for this app is to simply write out the users that signup to a database record that we can refer to for say like their profile information or anything else that we'd like to add in this case we'll just register a simple a display name but of course you could imagine the user providing some other type of profile information and for that we need to store it inside of a database anyway so we're going to write a method for that and I'm just going to call it set user data and we're going to pass it the email their display name and their status and so we'll just define a constant status of online so for this application we'll have a kind of a very crude present system that we can come back and actually make much better in the future but for now we'll just go ahead and set the user status online when they register and we'll have to think about how to mark the user as offline say if they lose connection or some it would be easy enough to set their status to offline in our logout method when we write that but we have to also look at how in general to set a user status depending on their current connection state to the application and not necessarily whether or not they've called a specific method so in any case this is what we'll do at the first pass and so let's go ahead and write this method set user data which will take the users email display name and status and we can apply types to these methods as well just use typescript and what I'm going to do now is go ahead and store the path in the database to my particular user and so we'll put that user at user slash and then just their user ID and so how I'll handle getting the user ID is just with a method current user ID which will right here in just a moment but first for string interpolation here I need a dollar sign and then we'll create our object here to push to this particular place in the database and will supply the properties and I'm not sure if with the latest version of JavaScript or not we even need to set the properties like that but I'm going to set them explicitly here maybe it's just something I recall seeing recently and I could be wrong so in any case we could definitely set set it like this and so then we can actually just use angular fire database to update a particular object so we use lists earlier so we saw that when we were retrieving a list of messages from our the message part of our database and so now we're going to have a separate parent note for all the user Center database and so we want to update a specific object so we just provide the path to that object which in our case will now be user slash the current user ID for which we need to write a method to get the carnies ready then we're just going to update and provide this data object here and we'll catch any errors and log them to the console okay so now let's go ahead and figure out how we're going to get this current user ID so that's actually going to be pretty straightforward I actually write this more towards the top of our class here and so we'll write like get a user ID which will be a string and we're going to say if this dot off state is not equal to null and returned this dot all state that UID otherwise returned identity string so we're just using a ternary operator here to say that if this lot all state returns something in other words our user is authenticated then return their unique user ID otherwise return in a B string here okay so while we're in our service here let's go ahead and finish it out since there's only a little bit more we'd have to do here to implement our login functionality so I'm going to write a login method here which will just take an email and a password and then the way that the login is going to work is that we're also going to return a promise here so this that if off got off dot signed in with email and password and we pass it the email and password and it's a promise so we'll write a narrow expression for this and we'll set the status to online again I know that this is really hacky and we'll set the user status with an email and status and then we'll navigate the user over to chat ok and then our set user status will be another method much like our set user data here except that we won't be setting the display name I just simply want to set an existing users status cue online and we'll do that using their email here and so this would be set user status ok and I've completely written this inside of the set user data method by accident alright so sorry about that come down here and write I don't want to update anything except the user status and so there's no need to pass an email either we just pass the status for the current user ID and then we set it to what we pass this method okay and so current user ID is not working for us and that's just because we have a typo here ok with a lowercase D so that should be working and then set user status yeah we don't need to pass the email because we can just get the current user by their ID because this should happen when they are authenticated ok so we could also write a few more methods in here just to name a few we could again implement social authentication in here there's a method to send a user and email to reset their password perhaps we can implement all of that in again in a later video but for now let's go ahead and try to wire up our sign-in and our login forms so I'll head over now to our signup form component okay I'm just going to go ahead and paste in our HTML for our signup form we do have quite a bit of markup here but it's all relatively straightforward so first of all just have a container div and then I've got a div class signup card which will wrap our form and I'm using this template reference variable signup form here to access our NG form directive we just have a basic heading here we'll put this sign up and then we'll have an email password and display name label and input that our users will provide and so a pretty straightforward input with a placeholder here then we have this two-way data-binding to email and we supply a max length do something very similar for password and display name and then finally we have a button here which we will apply a disable directive to if the signup form is not valid and then when the user clicks our signup button the Senate method in our component will get called which of course invokes our authentication service and so we'll be passing the display name password and email from our form here to our component which we can see here we store those as constants that we've been passed to our signup method on our authentication service and if that resolves without errors then we navigate the user who has now been authenticated to our chat route okay so let's go ahead and see if this will work for us so we'll head back over to our application and we don't have our nav bar written yet so I'm just going to go slash signup and it looks like as you can see our layout looks pretty bad because we have that height of 100 percent set to everything and we don't have our signup form CSS setup yet so let's go ahead and actually complete the CSS on our signup form so we can do this very quickly here and I'll just go ahead and paste this in then we'll go into too much detail about all of our selectors this but I will scroll up so that you can see what I'm doing here it's all very basic styling so we've got our card in our form input and then this container and the container I am supplying you background image for similar to the play that we did in our feed so let's go back to the page and okay so our signup form is looking a little bit more reasonable and my browser has saved a previous email and password combination so we use that and then for our display name I'll just put my name here okay and let's go ahead and looks like we don't have any errors yet so we'll click signup and see if this works and yeah it looks like we have been redirected to our chat which should mean that we are authenticated so now if I go ahead and try to post a message and hit enter we come down and I'm still seeing test user here as being the user on this message let's go try to investigate and see what's going on here so first of all let's head over to our firebase console and confirm that we do have a user who has been registered if you're not seeing it in your user licious go ahead and refresh the page here so it looks like our form did register a user and we have a user ID as well and the email looks correct so I'll cut over into our database or we can go ahead and minimize this and we should see a user's note here which has a correct display name email and status of online so it looks like functionally we have a working signup form let's go ahead and take a look at our message component and see if we can't determine why when I post a message I'm still getting test user I'm going to minimize this and we'll look in our message component at HTML and so I have a binding to the username so if we head into message component that TS so I recall now that we did some manual input of our username in the previous video before we had authentication setup so probably in our chat service if I scroll up yeah you can see I'm setting the username to test user and so now I can go ahead and uncomment out this user name property which is calling this user name and do the same for the email and then be sure they're getting set here in the constructor so we'll go ahead and uncomment out this code as well so if you watch the previous video you'll see that we implemented the ability to send messages before authentication was set up and in order to get that working and show a username out in our message component I just temporarily commented out our authentication code here and so here we're subscribing to the off state and if it's not undefined or null then we set the user to what gets returned here from this observable so yeah so this is actually just a firebase that user okay so now just to recap what send message is doing we get the timestamp and email and so that's all good we're getting the email now on the authenticated user and then we are getting all of the chat messages back from our database and we're pushing this new chat message onto it so the message itself will be passed to this function then we grab that timestamp we grab the user email and so now we need to actually grab the authenticated users display name or user name and so let's go ahead and in our constructor here what I'm going to do after we set our user is to actually locate that user in our live database so this is coming from firebase authentication but if you recall our display name is stored in our live database so I just want to very quickly revisit this just to show you here in our lot this is our live database where we store both messages and instances of our user object here as well and so I want to be grabbing this display name because this lives here over in firebase authentication I'll open this in the new and we just simply have reference to the email address when the user was created and when they last signed in and this user ID but the display name isn't isn't stored here so we need to do is to write a method that gets the user that's currently authenticated and that's basically just going to be a reference to the users path in our live database so we're going to subscribe to that and this will make sense in a moment here we're going to set this that username equal to the strip called it also user name in the database but we call it display name that's something else we could refactor for naming purposes so I'm going to write this get user method and we just need to get the currently authenticated user because that's the one that's sending messages of course so we'll say the set user is equal to this guy user that UID that's the user ID and then the path to that user is if you recall it's in our users node and then it is just at the user ID for that particular user so if we look back at our database this is the user ID here and so all we're doing is just querying for this node here which is going to contain the name and the user ID that's currently logged in we'll have user ID that we're looking for so I can just return this DB and we can use that object again thanks saying the fire database and pass a deep-ass so this will return a and observable that we can subscribe to and set the user name on the class here inside of a subscribe method ok cool so that should work the thing that we can actually do instead of our chat service while we're in here is we have a method to get the current user we can also write a method to get all the users and this will be useful when we write our our list here of users on the left side of our chat room so we'll set a path to them here and this will just be the root users path and we can just return this DB list this time to path so it's also a nice kind of way to see both see angularfire list and object methods on angularfire database in use so in the get users case we just want to return a list of all the users at this path and in the object case we want to return the specific user object that exists at this path corresponding to the specific user ID all right cool so now we'll head back into our message component just going to go ahead and we can close out the template and I'm also going to close on these other windows here okay let's head into our message component PS file and I'm also going to uncomment out his own message now and we haven't done anything to really implement logic surrounding whether or not a particular message is a user's own message but we will in just a few minutes let's go back to our page and go ahead and try to post another message go ahead and hit enter and send here and so now you can see that I'm getting my display name out to the page here that's looking good let's go ahead and try to register another user and then ensure that we can get another user supplying a message to the page but in order to do that actually we would need to log out and we might as well just write the nav bar now so that we can place a logout button here at the top so let's go ahead and do that so I'll head over into our navbar component we'll open up the template and I'll remove the boilerplate code and I'll go ahead and paste in some markup here I've got a nav bar class we've got our logo which I will supply in just a moment and we have our heading with a name based chat here so this is just something I made up there's no intentional relationship with any type of existing company or product with that name and then I've got a div to contain our links and so we can subscribe to that user property that we'll look at in just a moment and that user would of course have a user ID then we're going to show this div and so we're giving to show this anchor tag and we just use that with the start ng-if directive here and so when we click on this link we'll have a method called login in our component to course we'll call call upon once again our authentication service and log these are in likewise with something similar here for signup which will just direct the user to the signup page and again if users authenticated will say hello and pass in these errs email and finally if the user is signed in we will also provide them with the ability to log out by calling a logout method let's go into the component and so we'll import our off service I'll go ahead and import observable from rxjs and import vanilla firebase as well okay so as we saw from the template I'm going to be using a user property here which will be an observable firebase user we can subscribe to in the template using that async pipe and then we'll have a user email which we'll just set to a string and in our constructor here course we will be injecting an authentication service and just to avoid any confusion I will just have to call it off service and then inside of our ng on an it so when an instance of a navbar is created set this user equal to you a method on our off service called off user and we'll write that in just a moment here and in fact we'll also subscribe to it here to get the email okay so pretty straightforward there I'm not sure that we would even really need the if user I'll leave it here just for the time being and then let's go ahead and write this off user method that's going to be ultra simple it's just going to return the logged in user so we'll head over to our service and that is basically and this will be essentially the most basic thing that the office service should do is just return this that user okay and so that's pretty simple tended to our nav bar CSS now go ahead and paste the CSS in here so again nothing too fancy we've got a width of 100% on it and I will be using flexbox to style it a bit I have a logo that I made which was just really horrible and very simple hook so feel free to make your own logo if you like or I'll post a PNG up on github as well and yeah we're setting it as a background to a container div that has an ID of logo and then just setting the background size to cover and then explicitly setting a height and a width on this image which is already square so that should just provide us with an ability to size that logo as needed if you have really good design skills and can work with SVG s then you could make this even nicer okay in any case then I have some basic styling on a heading ID and then a links class where we had just apply some padding to the links that are in our navbar and then all of our links that have a parent with a an element of ID heading and then all anchor tags which exist inside an element of class links just setting some color and turning off the default underline that exists on anchor tags sending a hover value to change the color and applying a little bit of transition there and then something very basic for the user email ID okay so that's all looking good so let's go ahead and take a look back at our page now and we should have a navigation bar okay so yeah we have our nav bar set up we have the default fonts so what I'm going to do is head over to google fonts and we'll just come here and I'll go ahead and bring in open and then I think I was also using Roboto and it's somewhere okay so probably a bit excessive use of fonts here in case we'll go ahead and grab this it looks like google fonts has updated their styling here recently okay so now I'm going to come down into our index.html and inside of our head tag go ahead and paste in a link to the CDN here so go ahead and save that come back to our page yeah so we get a little bit nicer fonts happening on our page now
Info
Channel: Wes Doyle
Views: 16,323
Rating: undefined out of 5
Keywords: angular firebase tutorial, angular firebase authentication, angular firebase chat app, angular firebase auth, angular firebase login, angular firebase, angular 4 tutorial, typescript, angular 4, javascript, learn to code, chat app firebase, chat app tutorial
Id: p82OeXq_Aoo
Channel Id: undefined
Length: 42min 41sec (2561 seconds)
Published: Thu Aug 10 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.