Live coding a lazy loaded comment system with Firebase | Firebase Semi-Live Ep.1

Live coding a lazy loaded comment system with Firebase | Firebase Semi-Live Ep.1

Show Video

Hey everyone welcome, to the, first ever, episode of, firebase, semi, live the, live coding show where I live code it right here but you watch. It not live out there so. Today, we, are going to take on the, topic. Of building. Blog, comments. With, firestore. And serving, this site on firebase hosting so. The site I want to build I want it to be a static, blog but I want the comments, to be dynamic, and the, goal is is that the page needs to be able to load quickly, so. Let's take a look at this blog so. You can see right here it's just a really basic blog, that, you know I built very quickly and then down here I have this button called load comments. So the idea is is that all we have to do is load, the, static. HTML first, in the, CSS and then. When I'm ready to actually. Load the firestore comments I just have that be, clicked on by the user and it pops up lazily. So. Let's uh let's. Take, a crack at building, this. So. In my editor I have a web pack set up right. Here and I'm also using tailwind. CSS, to build out all my CSS, which, is really cool you should check it out but. We're gonna be mostly focusing, on firebase stuff today obviously and, the. Idea is is I want to use webpack, stung, keying or code splitting ability. So I don't have to load firebase, or fire store right away but. I want to start by building it the naive, way I want it to be. I want to build it in a way where we do have to load fire store before we load everything else just, so we can see. How. To improve it and how we can work from that base situation. So. In. This page, actually. In my blog with this little icon. I want to animate these because, i want to show what, happens, to other JavaScript, on the page if you're not lazily, loading things so, i'm gonna animate these and these should show up immediately on, page load but. It's, not gonna be that great at, first, so. I'm not gonna use a JavaScript framework or, anything I'm just gonna use basic, JavaScript, so I'm gonna use a class call, it comments, and I'm. Gonna kind of do everything inside, of this class. And. If you haven't noticed I'm also using typescript. Which. Is you very similar to JavaScript, just as typed so if you're not familiar with it don't worry you don't let it trip you up it's nothing too crazy so, what. I want to do is is I want to be able to get a hold of some, Dom elements, so I can animate, so. I'll grab the Dom elements, and then I'll run the animations, and then I know use some CSS, classes, for that so. Right here I have this header and we can see we have an h2, of blog title, of my. Blog and then we also have the image, ID of logo, so. These are the two ones I want to animate, so I'll make sure to get, them with a query selector. So. A type script you actually can put properties. On your classes, so I'll have one for, logo. And I, can say that's an HTML. Image, element, and it's. Gonna give me an error because I have initialized. It to anything yet and then, I also want my blog title, which, is an HTML, div, element. I'm gonna double check that it's. An. H2. So let's change that, HTML. Is heading. Element, and. Then, now we'll, use our trusty. Query. Selector, so document, dot, query, selector. And. So. Hash, tag logo, and. Then. You, can see this is actually causing an error because, typescript. Returns back. Was. Element, I think so HTML, image element or null is not assignable, to Oh, cuz I think I need to if. I, know. I think you need to say as HTML. Image. Element. Yep. Stop screaming I'm happy about that so now. It's in my blog title, so document doc query selector. Of. Hash. Tag blog. Title and. Then. That too as. HTML. Heading. Elements. Okay. Cool so now we run animations, so, what I want to do is I want to do just add some classes, so I'll call a method called like run all, right call it animate, header. So. I'll create that method, down here. And. This. Is going to be just two simple lines of code this dot logo. Classlist. So. Add fade. In up. So. They'll just kind of go from a zero opacity. And translate. The, y-axis. And then. This dot blog, title. Classlist. Add. Fade. In, down. And. Last. Bit so this actually, runs is I want to say new. New. Comments. All. Right, so. This will create, a new class which, will run this constructor. And you can see we'll call this code, so. At this point I need to serve, so I'm actually going to setup firebase, hosting to. Use it for local serving and I'm. Actually not gonna set it up the way that you've, probably used it before because, I want to be fun we want to do things a little differently, so I'm gonna set it up by hand so you can see all the work that the CLI is actually doing for you underneath the hood and this, is actually how I set it up in all my projects, because, I have so many projects, that like. The list is so massive that it take me longer to find my project, in the list than it would be for me to just set, it up here in the project, so. There's two files that are important for firebase, hosting and really just two files alone, that's.

Firebase. RC. So its dot firebase, RC you, can see that vs code gives this nice little icon with it so that's like a really good way of knowing that you typed it in right and then. There's also firebase. JSON. Which, we also get the, nice little icon for. So. With firebase RC, this is how you configure which projects, you're going to deploy to so, in this case I can write projects. And then. I start, with a default, project so you should always have a default, Park to deploy to and in, this case I think I call it fire. Semi. Live or. Maybe it's fire. Semi, live I, can't, really remember me. Check the console, which ways the console. I. Called. It fire semi, lives so I'm gonna copy that I. Did. Get it right nice but, the cool thing about this is this is just one type of project you can have you could have multiple you could have a staging. Alias, and you, could have a production. Alias. Or, you know just own whatever you can keep going on this and then in the. Command, line to switch you, would just say firebase, use. And. Staging. Or whatever the name of this key is and then that way you can deploy out to that after you, use that so, it's a nice little way, to manage multiple environments, but. In this case I just have my default. Project and this, is used, by default, so I don't have to say firebase use default in this case. So. The second is for are based on Jason and firebase. That JSON actually manages more than just, hosting, firebase JSON, can manage deploying your database rules your storage rules, it, can manage, your fire, store rules it does a lot of really cool things and. So we're gonna use it for primarily. Right now is with hosting, so we'll give it a hosting, key cuz it's the product we're using and then. The main thing you have to tell it is what. Folder. Do. You want to deploy your files from and we refer to this as the public. Folder so. You say the public folder is and, in this case I'm actually using.

This Dist, folder, so. I'll say public, is dist. And. There's also lots of other cool things we can do in this hosting directory, we can set custom headers so, you, do like HTTP, to push headers, we, can do, redirects. And, rewrites, and rewrites is how we mix, with firebase, with, cloud functions. So. There's lots, of cool stuff we can do we also can say ignore so, if there's anything in your directory that you don't want to deploy that, works out really well and I like to do this for like node, modules, or something like that so I don't accidentally, deploy all my node modules. But. For now I'm just gonna leave, it at this, and, with. This set up I should. Be able to come down into my command line and I'm. Actually going to tie tap, into my node. Jules because I installed, this locally, dot, been firebase. Serve. And. With, any look. It's. Serving, here on localhost, 5000. So. If i refresh, yay. We're, up and running alright, so this, is up and running that's great and I also have. Got. That one out that, should be gone, and that's still running but we also have webpack running on a watch command, so basically, when you type. Webpack. - - watch web, packs just gonna keep running after any changes so every time I make a change here it'll, just automatically recompile, and we'll. Just be able to refresh it in the browser which is pretty nifty. Alright. So. Now when i refresh we, see we have our animations, so that's cool we have something that will be able to C be slowed down by including too much JavaScript, on the page, so. Now to the firebase part, so. To import, firebase. Module. Syntax we want to import firebase, slash. App, so. This means we're just gonna import, the firebase app library we. Don't want to import, all of firebase, we just want to import what we're using so in this case we're gonna start by importing app let's. A star as firebase, because that's how typescript, likes it and then, I'm going to import just. Firebase, slash fire, store because that's my main feature. Alright. So. In this case now I. Have. Included fire store and what, I want to do is I want to be able to configure, a firebase. App and I'm, going to do it inside of this constructor. Actually, so I'm gonna create an interface. Call. It comments. Config. And. What. I want is an auth domain, which is a string and then also I, need, a project, ID which is what firestore needs just. A string, so. The, constructor, of this will take in a config. Just say comets config and then. From here we. Can create a firebase. A property, just firebase. That app app. And. Then. We'll also create a common, reference, from fire store so the type is located, at far based fire, store dot. Collection. Reference, so. It's a Pease type script by actually initializing, these properties, to. Do that I'll say this stop firebase app is. Firebase. Dot, initially. App and I'm, going to do it actually with this, config. And then. Now. That I have a firebase app I can create my comments, reference and something, I really want to point out right here is that, there's. Two ways of using firebase, apps you, can either create. Firebase, dot initialize, app and return, an app from the function or you. Can just call firebase dot initialize, app and then sort of globally. In a way you can, say firebase, dot, Fire. Store or whatever features you've initialized and, when, you do it this sort of global, way it works off of the default. App and. This. Is like a really nice and like you, know easy way to do it but honestly. I really, prefer, using, returning. Through a firebase, app because, if you ever try to unit, test your app or if you want to be able to run a different, app. We. Want to be able to run your different. Project, that is it's much easier if you can pass that app in as a parameter rather, than relying, on that default, app so this is just something. That it's. Pretty easy to do and it makes your life easier, when you want to switch projects, or report your code somewhere else so I really recommend, returning. The firebase app. So. Now that I have that created will create the comments, reference from fire store and I. Guess, before I should do that we should kind of talk, how we want to store these comments, in the database, so. With fire store everything, is collections. And then documents. So you have in a collection, is just a list of documents so, in this case it's a blog so I'll have a collection of articles. And then, each article, will be a single document. So in this case we'll have a key or an ID of, each document and. So I'll just call this one article 1 but ideally I'd want that to be some, unique article, or some unique ID or, maybe the.

URL. Of the page something, that I know I can key off of, so. This document, would be article. Data so maybe it would have like the article title, the. Author or, whatever pertinent, information this is something that we're not really gonna be doing right now in this specific, video but, what we care about are, the comments, so. Firestore. Has this concept of sub collections and that's a collection. At, the same path of a document, it doesn't, particularly. Belong. To the document so if you read the document, you're not going to pull back all these sub collection data but, they share the same path which makes it really easy to, organize. You, know it, makes, it easy to organize your data structure, so. Way. The way we're going to read comments is through articles. The, article. Key or ID and, then, the comments sub collection. So. I'm going to do that now let's say this dot comments, ref is this stuff firebase app dot. Firestore. Dot. Collection. Of articles. And, let, me put this on a separate line so it easier, to read so dot collection, of articles. Of. Actually. Instead of saying that collection of articles I guess, again you can do it two ways you. Could say doc collection, of articles dot doc of article, 1. Dot. Collection. Where's. That, BS. Code doesn't want to find the right type here, sometimes. If I just can't it keep hitting dot. It. Will listen to me dot I want you, there. It is dot. Collection. Of. Comments. So. I could do it this way and just keep chaining, or, I. Could. Do it like this, dot. Collection. Of, articles. Article. One. Comments. So. Whatever way you prefer I prefer to kind of doing the chaining, because it just. Feels like it's easier to maintain than just one string but you know whatever is your preferred method is totally fine. You have these comments, and what, we want to do if you look at the page is that we're gonna add an event listener, to this button and when, we click we're just going to read back all the comments and so, right now there aren't any comments in the database so we will, seed them after we write this code. So. What we need to do is we need to get more Dom elements, and in this case if we go to the HTML, we can see that the button, ID for. Load. Comments, is called. Load comments, it's. Pretty easy to remember so we'll, create our button, property, which is an HTML. Button. Element, and, we'll. Say this dot. Load. Comments. Is document. Query. Selector. Of. Hashtag load, comments. As. HTML. Button element, and if, there's any like super advanced typescript, user out there watching this telling. Me hey you don't have to do this as thing. Let. Me know because I would like not to do that. It's a big pain of mine, alright. So. Now that we have this button we're, going to do. What, calm if they call this dot add. Listeners. This. Is a good place to add. Listeners. So. I'll create a method add listeners. So. That's now happy, and, what. We'll do is we'll say this dot. Load. Comments. That add event. Listener, click. I'll. Name it the full thing event. So. Whenever someone clicks we're. Going to want to tap. Into this reference and we're gonna want to stream back comments, but, we're also going, to want to take this button, and make it go away because if they've clicked on it it's gonna load you know the button doesn't need to appear anymore but we will only do that after, the data has, appeared. Actually. Now that I think about it you, should probably take it away immediately because, if you click on it and. Nothing. Has happened yet, because it's downloading, over the network, you might just keep clicking on it because you're like why isn't anything happening and, if you're on a slow can section and you got a really, click happy user that, could be bad so let's remove the element immediately. And. So. To do that I'll say this dot load comments, class, list. Dot. Add and, then I have one called hidden, which sets its displayed, to none. All. Right let's. Run that real quick oh yes. Of course that's gonna break at times. And. So, it's refresh, if, I click load comments, doesn't. Like it. Must. Provide project, ID that's. Interesting. I thought I am, providing, project, ID no, I'm not actually passing any of that information I said I would pass all right let's.

Do That so we, parameterize this, constructor. The, taking config but I actually didn't pass, anything config, in so that's gonna. Be a problem so, fire semi, live, dot. Our. Base, app calm, and then. Project, ID is, fire. Semi. Live. Okay, now it's happy and so. It's really important, to understand, right here is that, whenever. You create a firebase, app a lot of your configuration. Details, are going to be based off of your project ID so, in this case for auth domain I always know it's the project ie ID dot firebase app comm same, thing if you use storage, your bucket, is your project. Name, dot, appspot.com, so, it's just kind of good. Stuff to know so you could do really quick configurations. All. Right so, let's refresh the page just get a phone mode and if. I click them button, it disappears. So. I think we're done here no I'm just kidding alright, so, this is an error that you get from fire store right now because we're, changing the way that date the, date, object is stored so we're, using this, time stamps, server, time stamps instead of native, JavaScript, date objects, so if you don't want to see this error it's actually pretty simple to configure that so let's do that really quick and. So. To do, that where. Am i creating my fire, store, right, here say. This dots. Firebase. App dot, fire, store. And I. Can say the, settings. Timestamp. And snapshots, is true. So. That built if, i refresh. It's. Gone all, right so let's keep moving, along, so. Now. That, we have this comments, reference we add the listener we, need to start streaming back the data so, with firestore. We have, real-time data, listeners, through the on snapshot. Method, so. With the comments, ref I can say this that comments, are after on snapshot. Provide. Me a call back so, in this case I can say here is the snapshot, and then, inside. Of here, so, where I can do any rendering. So. One thing I want to do is I want to kind of have this render, method and within. Here I can pass in you know the data that I need to render and you, might be thinking like, that looks kind of like react well it's kind. Of a nice. You. Know methodology, to do it this way because a lot of people are familiar with this render method and since. This is just a regular class, that. Doesn't have any, opinions. Of how to do things I kind, of try to use things that seem familiar so. In this case I'm gonna provide a little render method just so if someone else came and took a look at my code they would say hey that's. Probably where the render is so. That's just something that I decided, to do, so. In this case what I want to do is I want to take these comments, or the snapshots, and I want to turn them into actual, commet objects. So. To do that. What. I'll need to do is take, a look at the snapshot. Type actually, so. We'll click into snapshot. Why. Are, you not working with me so if I say snapshot, is declared, it's a firestore, no. Usually. Vs code when you click into this does it so we're do it a different way so. Snapshots, dot. Will. Tell us all of the, properties, or functions, that are on the, snapshot and, you can see we have a couple things that we can call there's dock changes. And dock, changes, we'll return to an array of well.

Document, Changes but that means. It's not the actual sorted. Information. That, or your state of your collection, it's what happened, so if, something was deleted, you would get an omission of a doc change saying okay this was deleted, and then you could use that toast. A little pop up that was like this got deleted or do an animation based on that so these are actual events. That happen, in your app and then. We have Doc's Doc's. Is the actual, state of your application so, in this case for my comets and is the actual list, of comments, so if something is deleted, that. Doc's will have that removed, where's doc changes, will be that actual, document. That was removed, and, then. There's testing, for empty there's a for each method to, loop through things is equal, we, can check out some metadata which is useful if you're doing offline. Changes. The. Query is the underlying, reference and, then the size so, how many documents. Are in the snapshot so. Doc's comes back as an array so one thing that I can do is I can actually map over, it so, in this case I can turn. It and then doc, has, a couple, of properties itself, it has data, which will return you the JSON representation, over the JSON object, that is not, the string form you. Can check to see if it exists, which is nice helpful method. There's get which is a promise, of getting, the data because it's also, shares. The same as the reference we, can see the ID we, can check, to see if something is equal we can see metadata and then also get the underlying reference which is helpful if you want to do any mutation. Operations, like set update, delete, so. In this case I just want to map the, data over, and actually. One thing the, data will do does will just return you the data but as you can see the ID is. On the document, not the data itself so. Right here this is sort of a you, know whatever you want to do kind of thing you can either store. The ID in, the document, itself, so that way you don't have to worry about getting, it from the. SDK, but, through this mapping method or you. Can just do it like this where you say okay let's return the ID. It says dr. Eide and, then. Mix. That in with the actual object. So. In this case this will be all of our comments. Let's. Bring that out to a separate line so. Now our comets is going to be an array, and it's. Gonna have an ID and, then, other properties, that come down from the server and from. Here I can call this dot render. With. My comments. So. This isn't gonna do anything iswhat a console, dot log my. Comments. Make. Sure that rebuilds. Do. A refresh. So. You. Didn't get anything and, that's probably because we did not yes. We did call that listener so let's do some debugging see. What I missed. All. Right so, I don't want this, file I want. This, this is my type, script file which is using a source map so it looks the same in the browser than it does in my editor and what. I want to do is I want to add a breakpoint at add listeners, and, then inside, and just kind of refresh and see what happens, so. Calls add listeners, and. Oh, cuz I have to click the button now that that is why it's the whole point of this so, I click the button and. The. Button goes away so that's good and, then. We're going to call on snapshot. And. I'm gonna wait and then. We. Get this message, that says could, not reach cloud firestore, back-end connection, fail two times most recent, error is this this and that and that's, because I just recently created this project right before I started like I mean like right. Before I started so, what I didn't do was, I didn't go into the console. And enabled, my fire store because, that way you only, want to create these resources, if you need them so I'm gonna go quickly go in and create that alright. So I'm in my console, and as you can see I have everything, up and running now and just, as a note I started in test, mode. And. So that means everyone, has read and write access to my rules which is bad which, is very bad, not so bad while you're developing but, it's nothing, that you should ever go to product so if you're gonna deploy this database out to production, you need to write rules and we're not going to cover that in this video but I plan on covering it and the very next one so it's gonna have its whole video. Dedicated, to doing this but, for now we're just gonna get things up and running, so.

I Want to add a collection we're. Going to have articles. And. We're. Going to have article. Underscore. One and, then. Field, we'll just call it name some. Article. And then, I will save. So. Now I want to add a sub, collection so in this case this article one is going to have comments and then. We'll have an auto ID. Here. And we'll, say the text is first. Because. That's what every comment ever. Is alright, so save. And. Then. Look at that all this stuff just went crazy, we, get in, the good way we, got our sub. Collection with our data and firestore responded, immediately and. We, can see if we finish mapping. Right. Here and just get rid of these break points. If. You go down get, rid of this error message you can, see that we got an empty omission at first then we got that when we actually enabled. Our API and then, we got this other one was when we added our data so, now that we have these comments, let's sexually try to render them. So. To render them I want to create a div. With the class of comments and then it just that's a P tag that's gonna be something simple for now and, probably. The next video and we do security I'm, going to do authentication as. Well and so we'll be able to kind of display a user avatar, or something like that but for now let's just get it so it's displaying text. So. To do that I want to, be. Able to create, a method called like create, comment, or something like that or actually even better what. If we just create a class college, comment, so, comments. Is the. Actual, comment list so it could probably call it comment, list, instead, of comments, that actually sounds way better so, I'll rename that symbol, comment, list. And. That didn't work out super, well as a comment. List. New. Comment. List okay and then, we'll have a single, comment, and, so. For, this we'll say the constructor. Of comment, and, we. Can pass in some data or something but. Really all I want to do I think about it just, do, one where it's like create, or something like that actually, you know it will. Just make it a function we'll, get to that later I was trying to build into some, custom elements which you'll see in a future video so. We'll, create a comment, so create create. Comment. And. This. Will take in a comment, which right now we'll just type to any. So. I'll create the parent, div so, that's, document. Dot create. Element. Div. Take. The div and. Class. List, dot, add and, we. Will add the class of comment, and, then. We will create ap tag so document, dot, create element. Of P, tag and. Actually it really bothers me not to have my, variable. Initialization, initialization. Statements, next to each other and then. We'll say P dot. Text. Content. Equals. Comment, dot, text, and then. Lastly, we'll take the div and append, the P, and. Return. All. Right so. Now what, we want to do here, I'll, say creative. Create. The actual, elements, so, we'll create Const. Fragment. Is. Document. Dot create. Document. Fragment, so. If you're not familiar with document. Fragments, they're a really good, and efficient, way of updating, the Dom and they, are a detached. Fragment. Of elements. Where you can append children. To modify, them and once you're ready to insert it into the Dom somewhere, you, can just append, the fragment, so it's a really nice way of a, nice performant, way of doing, Dominus, versions, so. What I can do is I can loop. Through my comments, and say comment dot for each, comments. And. Inside. Of here I can, create a comment, there, comet, elements. So it's a cost element, is this dot create comment. I'll. Pass in the comments and then. I can call the fragment, say fragment, dot, append. Child. Comments. And. Then. The last step of render, is I want to go to this comment. Placeholder. Which is sort of the container, for all the comments and I. Want to create a property, for it so I can append to it. So. The comment placeholder, is. HTML. Div, element. That's. Right it's a div it's a div and then, right here, and. Say this dots, comment. Placeholder. Is document, query. Selector. Hash. Tag, comment. Placeholder. As, HTML. Div element. All. Right so. Now that we have that, we can append, to it so. We have created our fragment, like, this dot comment, placeholder, dot append child of.

Fragment. Alright. No. Errors no errors. Let's, refresh. Let's. Go and, click the button and. We. Got an error, message and it says fail to execute append child on node parameter 1 it's not type of node, and. That's. Because, I'm. Adding, the wrong one. And vs. Code screamed at me and tried to let me know that to by having, that element be dim so should have caught that and. Because I typed this as any the, fragment, was they're able to do that so I just really set myself up for this one. So. Now if i refresh, click. The button we. Have our comment, so, this seems really cool you. Know if we created a comet form the, next video. We could start adding a lot of comments and everything but. What I want to showcase right now is while this works we're not doing things in the most performant, way so, let's prove that. So. I'm going to shut down the watch and, I'm, going to shut down my, firebase. Server. Alright, so now we want, to go in deploy so, to do that I'm going to go into my node modules, that's. Where my firebase. CLI, is locally, located, and do, a firebase, deploy. So. It's gonna go out to the. Project. To, upload it successfully, and we can, just go, out to this URL. And. We. Have our, little. Animation. Run if. You load comments, there. We go but. I want. To prove to you that we're, not doing things as performant, ly as we could, so. Let's take a look at a few things here I'm gonna open up the network tab and I'm going to refresh and. We. Can see if you've got all that, we are loading for assets, which is really small so that's cool, but. As you can see right here oh it's. 2.4, megabytes of JavaScript, which is crazy but that's because I'm also deploying all of. My source map stir-crazy heavy, so I need to go actually and do a production, deploy, so, now, what I want to do is I want to go to my web pack config and change development, into production and I'm pretty sure that there's a flag to do this and so if you know that just leave it down in the comments but right now I don't know it off the top of my head and. So what I want to do is I want to build, I'll say yarn, build. Because. That's where my web pack build is, aliased, too and. So, now it's gonna go through and it's gonna take a little bit because the production builds, are a little more intensive. No. And it's gonna give me some, it's. Giving me some problems saying that this is really big and oh it's because I'm still in lining. The source map all, right so let's just, comment that out for now and if there's also a way to do this is commenting, it out let, me know in the comments. So. Let's run that again. Make. Sure that I'm not still. Including source maps somewhere. Okay. All, right so web packs giving us some. Some. Warning, an asset size limit and I will cover that in in. A little bit so. Now that we have something, less than you know two point four megabytes built I want to go to ploy it again node.

Module, Stop in firebase, deploy. All. Right so refresh, and. We. Can see right here that, this is a little, smaller and the, fact that it's ninety four kilobytes, so that's all of this web pack code that's all the firestore. Code and all of our app code, and right. Now we don't see any problems, but this is a pretty good connection so, let's see, where this can be an issue, so. I'm going to go to a site called webpagetest.org. So. Here I'm at webpagetest.org. And, one. Of the things you can do here is you can enter in a URL, and then set how you want, to test it with all these crazy options, but, you can kind of feel overwhelming, so there's actually a, page. On the site you can use code easy mode so all you do is paste, in the URL that you want to use and then you, just, start the test, now. This can take a little bit depends on how many people are using this service how, long it takes to run the site in this case I'm hoping, that it doesn't take too long so, while, this is working, alright I'm gonna fill the time because otherwise it could be sitting here for a minute or two. So. What I want to do is is I'm, trying. To showcase that when. We're doing these two imports, here at the top these, have to run, before all this other code does and what I'm really trying to show here is that this animation, isn't, going, to happen until this. Code is, executed. And if you think about it that doesn't really make sense like, I should be able to run my animation, before my, comets, are loaded because my comments, don't have to be loaded until I click that load comments, button so. What I want to do is is I just don't. Want these imports, at the top level I want, to do them dynamically. And so, the way that webpack. Lets you do that is through this dynamic. Import. Function, where you can say import, firebase. Slash app and then. It returns it as a promise, and so, inside, of that promise we have access to the firebase module, but, what's great is is that it's not in our critical path and, webpack. Actually goes out and splits. That into a separate, file and that file. Is only loaded when, we click that button. So. Let's go down here to the, add. Listeners. And. What we want to do is one that's clicked we. Want to import. Firebase. Slash, app and. Then. We. Could do, this through. An async. Await, so. I'll say constant. App is, firebase. Import, firebase app, I'm. Sorry firebase. And. Then. We. Could await, fire store as well awaits. Port. Firebase. Slash fire store. And. This is giving me an error because there's. Some issues, with it right, now and. The package is a little bug that we, need to fix so I'm, going to hack into my new modules, to fix this really quick and. It's, not a good solution but. It will work and this. Is something that will probably have fixed by the time this, project. Goes out so. If I go into. The. New modules, follow, my alphabet, ABCD. Firebase. And, then. Go, into fire, store and kind of package JSON. I'm. Gonna do here is I'm going to add a, typing. Folder. And I'm. Going to say it's dot, slash. Index. Dot. DTS. I think. That will do it. And. Then I'll restart, the TS server and. Then. Here in a second it should stop complaining, awesome. Ok so you, shouldn't have to do that but. This, is basically, what I did was is that we have some miss configuration, and the or, we don't have it perfectly, set up for, these dynamic, import types and so I'm basically tricking. Typescript, but it's not really of any consequence, because we're not importing, any types from this all. The types come from the top-level, firebase, so. It's just something that we need to tweak. So. Now that we have a firebase loaded, we can actually see something pretty interesting here if. We do a. Is. It yarn. Watch to start rebuilding our, web, pack. Web. Pack is watching the files you, know I got, a save I think to trigger it there. We go and we. Can see that now we have. Zero. Dot bundle a bundle, a two bundle a three bundle and those, are actually the asynchronous, chunks. So all of our codes not just in one bundle we, only we. Only will get those pieces of code when we click that button. So. Me. So. To prove this it's, reaiiy, got, to run the server. Let's. Do that real, quick. In. Firebase. Serve. Let's. Refresh, and, we're, getting an air about firebase, not being defined, let's see why that is.

Well. Formats, it's hard to oh yes, because we haven't reflected our code all the way yet so, that's kind of why we're we, still have some typescript, errors we still have some we, have some issues but we'll, fix that here in a second let's take a look at the page load so, you can see here that our first view comes in four seconds, and this is on a slow 3G, connection and. The load time is 6.5, seconds, so, that and, then this first you is at 6.5, seconds, in 6.2, so there's some variations, because it's a mobile network so, let's do this middle, one so, we don't know the filmstrip view and, I can see that at 4 seconds. The, page was, first loaded, and. What. I want to do actually is I want to check out fully loaded and I, want to create a video of this which is also going to take a second, and, what I want to show is is that that, animation. Just, sat there and it couldn't actually happen, until firebase, loaded. And. So. When we split it out that animation, will be able to load so, four, seconds. And there it is see look right here. The, animation, didn't run it just set there set there set there set there and then it, ran around six point three, six. Point two seconds, and, if we look. Back that, should be yep, like, I thought that's exactly. When our bundle, kind of ran and then executed. So all of our Java scripts, had to be downloaded, for animations, to run which is you know which, shouldn't be the case so that's what we're fixing. Now. So. Let's go back here, and. Let's. Figure out what's going. On so if this firebase, and so all this. Nice. Type scripts not working, right now but. Basically all this code isn't going to work and that's because. We. Have as. Because we're loading it asynchronously, now so. What, I'm going to do is I'm just going to copy, it right here, and. We're. Going to paste it right in, here. And. So the config, now we need to create us a script. A private. Property. And. They. Want it to be in the, constructor, so we're going to get, rid of that because it no longer will be a property, since being asynchronously, loaded but there's some cool stuff we, can do with observables, for that. So. We'll turn these into variables, for now. All. Right, look, look look look everything, looks, fine now so let's refresh, it let's. Check out our build. There. It is all right so now let's go back to, this refresh. Actually. I want to go back to using the development, build so I can read the code and have, source Maps. So. Refresh, I need to wait till rebuilds. So. That's just, safe, so it does its thing. Gonna. Build. Why. Aren't you building, so. The clip X is betraying, me. Just, gonna run the watch command, again. All, right it's, not refresh. We. Have our source maps back and. What. We can see right here if we go into the network is. That. We just have this bundle jeaious but it's even, with source maps this bundle is. 27. Kilobytes, which if we got rid of source maps if you identified it and compressed it it would probably only be a couple of bytes, which. Is really great and if we refresh, we can see it's the same and, now, when I click this load comments.

We. Get 0 bundle one bundle two bundle this is all these async, chunks that we're loading and then, our comic comes in so. Now I'm going to go back and. Do. A production, build, again and deploy. And test on, webpage tests. You. Know modules. In. Firebase. Deploy. So. I'm go back to webpagetest, and actually what I'm going to do right now is. Just use go, back to webpage tests, slash easy. And. Start. Test, so. This is gonna take another, minute or so basically. What we were able to do. Is. If. You look we. Have nine, kilobytes, for this bundle so in, nine kilobytes, which still seems pretty heavy oh that's because we did not minify, it so, if we minified, it it would be much. Smaller and it's, still including, source maps so. That also so, I think to not include source maps I not only have to comment out this. But I need to go into my. TS. Config, and, say. Source. Map false. But. Still this would be under, I think this would be a couple of bytes if we didn't have source maps and if it was minified. And. So. But we're including much less and then. When we click the button. Then. These things, come, into play and so, it's great is is that we are optimizing, for our page load and then other things that are heavier like, like. Fire stores. We. Can then decide, that we're gonna load them only when they're needed and so, in this dynamic way and there's actually ways, we can make this really fast to which we'll cover. In a future video and we make things more performant, but what we can do is we can actually use a. Attribute. Call or a tag called a link rel preload, which will preload it in the background while the users reading the blog post and so when they click on it it will be loaded and it'll, be lightning fast and you can do something similar to with a serviceworker. Alright, so we can see that our first view is 4.5 seconds, 4.8. Which isn't, all that different than before but. That's because it's our animation, that we are, worried. About and we can see right here our bundle, ran. At about 3. 3.3. Seconds, and if we would have actually removed. The source maps that have been way faster, so. Let's go and do, it fully loaded. And create, video. So. This is gonna take just about a second, to load. So. Now that's loaded, let's take a look, scrub through then, at about C. Or 4.3, and you look at that as it loads our our animation, runs immediately, so, it means we're no longer waiting on any, other JavaScript to do that our animation, just, goes. Alright, I think that's a good, cutoff, point for now in the next video we're going to you. Know get the, source. Maps out when we deploy so we can see get faster there we'll do this stuff with the pre, loading to get it really, quick but, what I also want to do is I want. To, clean. Up some, of this code because if we look at this asynchronous. Part it's kind of a mess we have this, async. Click. And then we have an async, import another async. Import, and then, we have another, async. Snapshot, there's a lot of async stuff going on and so I'm a huge fan of rxjs. And I would like to use rxjs, to sort of simplify this into one pipeline and then, also use, security. Rules to get this more secure, since it's not just open and then, create a comet, form based on that so we can add more comments, authenticate, people and make it secure so, thank you for coming out to the very first episode of firebase semi live the, live, coding show where I live code right here and you don't watch it live out there if you have any, comments. Of things you want us to cover in the future just, leave that and make sure to subscribe for, any future videos, and, I'll see you in the next episode. You.

2018-09-09 21:30

Show Video

Comments:

Awesome video. Great job @David... You make it look so easy! Thanks

Thank u for this awesome video and series

Give me a timeline of these videos please. Weekly? Monthly?

skott1e Monthly is the plan! We’ll see where it goes from there

amazing video, but please use JavaScript instead of typescript.

David, if I had been on that flight, I, too, would have been freaking out about the turbulence.

Why does it always feel like it's just me!?

Thanks for the video but hy is it so much work to write a simple info page with some text and comments. Almost an hour to do that?! Shouldn't that be easier to do in 2018. Also, why not use web assembly and real-time database instead of firestore?

It takes 10 times as long to do anything while you're talking about it

Great video! Did anyone catch in the end what he said he wanted to clean up the async code with? Arch js? Does anyone have a link?

RxJS! It's the best! We even have a new official Firebase library with it called RxFire. Stay tuned for more info on it. https://github.com/ReactiveX/rxjs https://github.com/firebase/firebase-js-sdk/tree/master/packages/rxfire

This is an awesome video....You really explained a lot and they were thorough....nice job, looking forward to the series

David East is back to give us some lessons!

Amazing tutorial, hope the next video comes out soon!

So I think I'm done here xD

Someone has to stop me

Firebase guys just neglected firebase real-time database.

I use the RTDB every day! I picked Firestore in this case because I want to build an offline comment system in another video.

Firestore is firebase but with collections and documents (sort of like mongodb), still real-time database, just better

Thanks for this, David. Really fun to watch.

This is amazingly useful!

Awesome example, keep doing videos like this!

cool!!!

Great stuff, looking forward to the series. One thing I would like to see is, what to do when you have lots of comments - e.g. 1000. How would you go about loading them a page at a time?

RxJS would come in handy for the data flow. However the real problem to solve is managing the multitude of DOM elements. If you load 10k comments and each comment component has 10 DOM elements that's 100k DOM elements loading all at once. The page is gonna freak out, especially on lower powered mobile devices. The solution is to build a "virtual" list that only displays what's in the viewport. This is no easy task. Perhaps we'll get to that towards the end, because I'm gonna need some time to build that.

Im guessing that rxjs is playing a role. At least for an endless scroll type.

The best tutorial I’ve seen on optimising using web pack. I like how you introduce tools you use for your development. Lots of nice tips and well presented. Thanks

BEST BLOG POST EVER

More vids like this pls

omg, I needed this so bad

Did you just show API key in public vide ?

Please what IDE is he using?

Nice tutorial! Where is source code of this?

Probably because there is a bigger market for more of a general database such as firestore, vs the smaller use case of hyper-real time. They both are super useful, but I think firestore is more flexible and applicable to most apps.

Ok I did it but for some reason my 3.bundle.js was 330kB, this isn't fair David ;P ;P

Maybe everybody else is just screaming on the inside, like I am.

About the as HtmlButtonElement thing, this is because document.querySelector can return null, thus the type of the variable should be HtmlButtonElement | null, which is safer as it prevents class cast exception (or its TS equivalent) and also makes you handle the case where the element may not be present in the DOM. PS. I'm in no way an advance TypeScript user, the warning you got the first time was the hint

How about npx firebase?

You should too. Firebase web config API keys are meant for public eyes

Visual studio

Visual Studio Code

Very well done! I would like to see in future videos how to manage a staging and a production environment with Firebase

Please more of this.

Noooo! The more TypeScript the better!

what terminal theme do you use?

Semi-Live Ep.1... learned a lot of cool stuff in this video... Thanks Will there be an Ep.2? 3 etc? a little gift back that you asked for... ctrl-/ for commenting out in vscode :)

Other news