Using React, TypeScript and Firebase to build a multiplayer card game.
Firebase is the go-to for many developers when they need a quick storage or authentication solution for a personal project. Often, React is also their choice of frontend framework. If you've used them before, you know that Firebase + React can make for a powerful combination in getting your idea to production quickly. I recently built a version of Rummy 500 for two players to be able to play in real-time using that exact stack, but with the addition of TypeScript. We'll go over a few reasons that make this trio such a great package, and some quick tips on building your own React + Firebase + TypeScript project.
Joon Park is a Software Engineer at Google, based in Chicago. I'm primarily focused on web frontend development - there are very few things I love more than building a clean and intuitive user experience! I was previously a Frontend Software Engineer at Grubhub, and before that I was at Northwestern University where I graduated with a BA in Physics and a BM in Music Composition. While I was a student, I was a fellow for Knight Lab and a researcher at Fermilab. I've also taught Python to a classroom of high school students at the Adler Planetarium and worked part time on Census Reporter. As a young developer I'm excited to continue feeding my insatiable appetite for learning.
OK, well, I'll just launch off here, try to keep under time on my slot. My name is June. I, when I was asked to do this talk earlier in March, was canceled. That was actually a front end software engineer up shout out to my former co-workers that GrubHub coming. I worked on the restaurant side of the business there. Now I'm actually a software engineer at Google, and so I work on the search front end for the G Suite apps. So a few months ago, I built an online web app for me and my friends to play around me. Five hundred, even though we were not at the same place. And I use this react firebase type script stack that I think is really great stack for a lot of developers to use on their own projects. I'll be going over a description of the what and the why to start and then we'll dive right into some interesting lessons learned and advice I have for for users stuff. So we'll do a quick overview of the technologies involved here. I don't really think I need to speak much about react to this audience, so we'll skip that over. But, Firebase, some of you may have used already, some of you may not have heard of it. It's this back end as a service or you might have heard of it as infrastructure, as a service provided to us by Google. It really quickly allows you to set up and interact with services you might need for projects such as a database file, storage, application, crash data analytics. It's got a bunch of stuff you can kind of pick and choose what you need to to provide essentially almost a complete back end to your front. It really comes with a nice, clean, understandable API. The docs are filled with lots of good examples. So highly, highly recommended. Most of you probably already heard about TypeScript in some manner, shape or form. And we're all that briefly mentioned it. Some of you may be already using it. It's Microsoft, increasingly popular typed version of JavaScript, and it's a superset of JavaScript. So it means you can intermingle JavaScript with typescript, which is really nice for existing projects that are not in that script. It's got a lot type inference, meaning there's some things that you just don't have to write it kind of figure out on its own. If you have IDs that have nice integration with TypeScript, it's really easy to make your own types and kind of autocomplete, API signatures, things like that. So makes things really easy. Before I go forward, a quick disclaimer. I'm not going to talk about any of the component libraries of the solutions that I used for the sake of focus and stick of time. I'm happy to discuss that with anyone individually. If you wanna ask questions about that, please reach out. But that won't be the focus today. All right, so what does this stack actually give us? One of the biggest things I think the advantage of the stack is just how fast you can get from zero to production. Our base makes it super easy to set up a lot of like the command line tools. You just run a command. It's kind of set up for you. If you don't use the command line tools, the console, which is really good, it's easy to scale if you ever take your application or your personal product to the point where you need to do that. You can do that pretty easily into the UI console they have as well. On the typescript side set up once again, if you use create ReachOut super easy. They include a typescript option. Now that comes with a really nice default template. So if you think about it too much, especially if you add Esslin on top of that and like a nice idea, like visual studio code that supports all these features, you really can just start like you can just type a few commands and just go. And then you're really like getting to a point where you're writing logic really quickly makes this front and focus firebases go to choice for many developers because it's easy to set up and and. Also on top of that, it's well designed and well documented for the most part, and especially for the Hawks, which I'll get to later, but for the most part, you can really just worry about writing a front in logic instead of any of the data and interaction layer, anything like that you would normally have to do so. Super nice to use Firebase in that way simply about authentication. Also, like a lot of uses of Firebase come to our store, which is the real time database that I'll be talking about for a bit. But they also provide an authentication solution that makes it really easy and fast for you to allow that as part of your app on the typescript end focus, meaning you can focus on your business logic instead of worrying about trivial things like which fields does this object have? Again, these are all things that you won't ever have to worry about once you start using TypeScript, because it's kind of suggested for you of note about security. So obviously I'm not a security expert, but I know that a lot of people, especially like me, just want to, like, get something out there. I don't really want to have to worry about all the details. They want something secure that just works. Right. And the off part of Firebase kind of takes care of that for you. Not only do they take care of the off part, they literally give you a built in UI that you can just drop into your application. And all you have to do is subscribe to a user's login log out event and everything else can take more care for you. Super nice. I'll get back to that more later. I highly recommended and on the database side, the security rules that faster kind of allows you to write on the on your console makes it super easy to specify who's allowed to act, which parts of your storage. So super helpful, remember? And last but not least, tons of resources out there for both Firebase and TypeScript. They're pretty popular choices now. So it gives us a wealth of existing stack overflow questions, dog samples. So just like react, both of these tools have a pretty strong community. All right, so let's look at the actual app here. What did I build? Well, I built an online version of Army five hundred sculpted Dota two players. If you actually played for me 500, you know, it's for multiple players. But this app is for two players only if you don't know what the card game is. Very simple explanation. It's just a card game where you try to lay down the most valuable cards to gain more points than your opponent and the app itself. I use Firebase off UI, like I mentioned, to to help authentication. Once users are logged in, they can send game requests. So other users then once they accept that request, the game starts. And you know, everything about the game as well as the requests themselves are in real time thanks to the real time nature of the virus or storage. Here's my data model. For the sake of time, I'm going to really not dwell on this too much if you're interested. Feel free to ask questions, or I think these slides will be hopefully made available somehow after the presentation. So feel free to take a look at it. But it's going to slide over that for now and to get to the interesting part. So now for the lessons learned and the interesting test. So using typescript with your act is not at all a language or in fact learning a new framework, even many people think that they have to learn a whole new set of syntax. But that's really not true, especially now with hooks and really great type inferences. You really don't have to fear too much from the JavaScript. You already know you've never written any type languages before. You might have to learn a little bit of type syntax, but it's not too difficult. And especially if you have experience with type languages with Java, like you'll you'll really hit the ground running. One added benefit of this is that it will help you get better at running docs, so especially if you're just starting to come onto the community or get more experienced or want to get more experience, you know, docs are an important way to do that. And a lot of docs use typed languages and or other type syntax to kind of describe their API inputs and outputs. So really good skill to have. All in all, I just want to stress that, like, you really don't have to change your way of thinking, especially if you have tools like ESL and enable or you just write the code. You usually write JavaScript and kind of follow the rules and IDs autocomplete suggestions and you'll be surprised how quickly you can you can get productive as as a beginner to typescript kind of going off of that. Make sure you pay attention to type errors, especially if you're learning, TypeScript, and kind of learning to use it with other tools. I know at first this will probably annoy you a lot, and I know it did. When I was first learning typescript, it was like here all these errors I never had to deal with writing JavaScript know. And some of them sounded verbose. Some of them were confusing. But really, don't let yourself off the hook for about these errors. Don't use hacks to get around them, because 99 percent of the time these errors are telling you something important and the screenshots kind of contrived, but you can kind of see that it is telling you exactly what's wrong. And like, if you take the time to dig in Google around and ask about your errors, and more often than not, it's you find that it's a common problem that typescript beginners have and you'll learn something really important from it. And as you do more of that, your typescript will become to begin to be more informed and you'll start to catch it bugs more easily, etc., etc.. The other typescript tips. So there's these things called index signatures. So think that. Imagine you want to write objects that contain like dynamic keys. So for example, like you have an object that has user IDs as keys and then object the values themselves or other user objects that contain some information about the user. That's pretty common, I suppose, the keys. So these user IDs would be called index signatures. And TypeScript, and one thing about index signatures that you can't have indexed signatures at the same level as other string fields in. TypeScript, just a little bit of a bummer, but there's definitely a nice workaround, which, as you can see kind of in my round data type that I've posted here, this UID string that you see as the example of an index signature that I'm talking about. So I couldn't put that right at the top level of the round data structure because the ID string field is already there. So a workaround that is often done and is suggested is just nested under another stringfield gives you the added benefit of using another variable name to kind of describe what you're putting in there anyway. So. No tip, don't be fast and loose with your nose and on defense. I know a lot of people, for a lot of people, JavaScript kind of allows you to do that. And to some, it's kind of a strength. But TypeScript is kind of the opposite. The strength of textures is forcing you and your code to be strict and meaningful. Right. So make sure when you do allow Nolan on the phones and your types that it holds some some actual meaning. For example, you know, null in your variable could could mean a value is not yet loaded from asynchronous call like that's a solid meaning is assigned to the null value. Be mindful of other API types that you pull and then also allow null and undefined. These can easily lead to bugs if you just assume that those won't ever happen. So that's another nice thing, that if you pay attention to types and be strict about them, it'll really help you catch those books. All right, now moving on to the firebase side, so let's talk about Hooke's a little bit. I don't know how many of you are familiar or like, I guess have kind of used hooks in production or just starting to get to know them or already an expert on hooks. I mean, I think people are kind of all over the place right now, but there is definitely some some positive momentum toward hooks as a community especially. And I think more often than not, you're going to write these hooks, especially when you're interacting with guys like Firebase. You're going to want to write hooks that kind of pull data from Firestar, for example. On that note, I would want to highly recommend everyone to do that yourself. So I found that writing faster hooks kind of helped me understand. You know, you say use effect the very basic bare bones of how Hooks works and what what is a hooks lifecycle, quote, unquote. I know that's probably not the right word to use, but you know how to really manage and write your own hooks and know doing that using Firebase, if you're interested in really understanding how you should write hooks and paradigms and the best practices, and I would highly recommend doing that yourself. There's an article called a complete got to use fact. Some of you guys might have already read it. It's by Dan Abramoff and it is probably the best article you could read out there that explains how to use this effect, which is I find that a lot of people that's the hook that a lot of people have issues understanding. So you haven't I would definitely check it out super long, but it's worth your time. But if time is not what you have and you need a stack that will just get you to production as quickly as possible, then there's this really nice package, Riak Firebase Hooks. So if you just Google Riak Firebase Hooks, the first one that comes up and the API is pretty great. It's straightforward. And if you're short on time, that's the one I recommend using. So moving away from storage, just talk about off. Right. So this is the part again, that people usually want to just drop and drop in and kind of forget about and let it work on itself. So on the left here, you see Firebase off dropped into my app, super basic bare bones, because my app is kind of still MBP, but especially if you're map or app is already kind of using design similar to material. It looks pretty, it looks pretty nice. Blends in well. And in the middle here, you can see the actual demo of the Google posted themselves listing like all the various Sinem provided. I think they have a lot more than this too, if you're looking for others. But really like it just there's a real component that you can pull and you literally just plop, plop it in into your app and it looks like this and you can just go to the console like click which ones you want to provide to the users. And that's all like it's all you have to do. Super nice one to use. The real component that Firebase provides don't use the plain JavaScript component because that can get a little bit tricky with the lifecycle and stuff. So I've linked here on the slide where that reaction resides, if you want to use that. All right, let's wrap up with a few other firebase. So casting typescript has casting like many other type languages you do if you are writing your own Firestar hooks, you do need to cast your data to the types that you're using on your front end when you pull them down. This can be a source of bugs because the faster default like data center functions, they just return the type of any. So just make sure you've got the right types that when you're casting arrays and Firestar are kind of interesting, they're really the one and only pain point that I have that I really wish was a little bit better. And Firestar, there are some restrictions. For example, you can't store arrays of race and Firestar, so, for example, like, say you have tuples, right? And TypeScript, that's just JavaScript Paré underneath. So if you want to start an array of tuples and fast or you can't, which is kind of a bummer, you can, there's a bunch of workarounds so you can use like an object as a workaround. The official docs kind of recommend having objects where the field is like the string key that you need it to be and then the value is just true. I prefer writing objects that have integers as keys and then the values can be more than just strings. You can be complex objects that you need and then when you pull it down, you can just call object out values on that object and that will turn it into an array and you can kind of use all your favorite array methods and so on, so forth. So kind of a kind of sucks that you have to do a workaround that way, but. For the most part, I found that, you know, you won't necessarily run into those issues, so not the not the force issue if order matters. I would also be careful with how you update your fire story. So the built in our store update methods are kind of there to allow you to use a phrase, a set. So on order collections. And if you if you do care about the order of a year of our store, then you kind of have to manage those updates yourself. So I would be careful about doing that. And last but not least, be organized about your functions that interact with Firebase. Right. It might be obvious to a lot of us if we've done a lot of development, but really you should be extracting all the firebase related logic into neat functions and kind of call them in your components as needed. And that's where the Hooke's I would, for example, like keep the real time update Firestar function separate from the functions that get out once. This can be a real common source of bugs. If you're like calling some password data and you're like, why isn't this updating? You realize you call the function, etc, etc. So keep them in separate files or even better, like establish a strict naming scheme for yourself. So like fetch versus subscribe, that can really, really help one that tip on the organization aspect. I would do all your firebase initialization and one file and then have all that stuff like exported that file and then other firebase code can import from there. And that will kind of help you avoid circular imports and keep your initialization card running only once, which can be also another big source of blocks. A lot of people kind of try to use Firebase in the app, so try to get them. All right. There's a bunch of links that I want to share. There's really too many useful links that I can really fit on one side. But this is kind of the pared down version. I hope you got something useful and some good advice out of that. And hopefully I kind of encourage those who haven't use the stack before to try it, especially in your own project. And yeah, I guess we can do questions.