{"id":1141,"date":"2018-12-15T23:00:00","date_gmt":"2018-12-15T23:00:00","guid":{"rendered":"https:\/\/weichie.com\/react-firebase-chat-app\/"},"modified":"2024-02-05T15:44:41","modified_gmt":"2024-02-05T15:44:41","slug":"react-firebase-chat-app","status":"publish","type":"post","link":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/","title":{"rendered":"Building a Firebase Chat-app with React, React Router &#038; Authentication (part 1)"},"content":{"rendered":"<div class=\"default__block container-fluid lg\">\n<p>I want to start creating apps with React, and what better way to do this than with a real-time application that other people can use? Making &#8216;real&#8217; stuff, gives me more motivation to start learning new things. I&#8217;ll be building a React Chat application with firebase and will blog along the way, to let you know how I did it and where I struggled. Hopefully it can help you getting started with React or Firebase as well!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<!--more-->\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/react-firebase-cover.jpg\" alt=\"\" class=\"wp-image-750\"\/><\/figure>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-project-setup\">Project Setup<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>You can see a live demo of this application here: https:\/\/chat.weichie.com (no longer available). You need to register an account first before you can see the chat. I did not put any effort into styling.<br><br>The GIT Repo of this project can be found here: <a href=\"https:\/\/github.com\/weichie\/react-firebase-chat\">https:\/\/github.com\/weichie\/react-firebase-chat<\/a>. Feel free to have a look around!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p><a href=\"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app-part-2\/\">PART 2 IS FINALLY HERE!<\/a> Make sure to check it out once you&#8217;ve finished part 1 of course.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>I am just starting out with React myself as well, so if you are an advanced React user, this blog probably can&#8217;t help you. But feel free to leave a comment with suggestions or feedback! Assuming you have basic knowledge of ES6 and React, I&#8217;ll be using the <code>create-react-app<\/code>, <code>firebase<\/code>, and <code>react-router<\/code> npm packages. So no redux or any other fancy library.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h3 class=\"wp-block-heading\" id=\"h-let-s-get-started\">Let&#8217;s get started!<\/h3>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>First let&#8217;s create our new react project!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">create-react-app chatbox<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>After this is installed, manually browse to this folder and take a look at the <code>\/src<\/code> folder. There&#8217;s a bunch of files that I personally do not like, so I&#8217;m removing all files in this folder EXCEPT the index.js and index.css files! Before we&#8217;ll start, we also add the react-router and firebase packages to our project:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">npm i react-router\nnpm i react-router-dom\nnpm i firebase<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Now that all our dependencies are installed, we can go ahead and creating our folder structure. We need a &#8216;homepage&#8217;, where all our chats will be displayed. And an Auth folder that will have all our views for authentication, like user registration and login etc&#8230; We&#8217;ll create a <code>\/components<\/code> folder inside the default \/src folder. Afterwards, inside <code>\/components<\/code> we&#8217;ll create a <code>\/Home<\/code> and a <code>\/Auth<\/code> folder. Our Home folder will have a Home.js and a Home.css file. The Auth folder will have an Auth.css, Register.js and Login.js file. Here&#8217;s my folder structure:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre class=\"wp-block-code language-bash\"><code>- node_modules\n- package-lock.json\n- package.json\n- public\n- README.md\n- src\n    - components\n        - Home\n            - Home.js\n            - Home.css\n        - Auth\n            - Auth.css\n            - Login.js\n            - Register.js\n        - index.css\n        - index.js\n- yarn.lock<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Let&#8217;s fire up our local server to see what we have so far! I&#8217;m using Yarn, but create-react-app will tell you in the terminal what commands are available for you if you don&#8217;t have yarn installed. Make sure you are in the root of your project before you run the command.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">yarn start<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Once the pages is loaded, we should see an error. (as I removed App.js to cleanup my project). So let&#8217;s start building our Home.js component:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ \/components\/Home\/Home.js\nimport React from 'react';\nimport '.\/Home.css';\nclass Home extends React.Component{\n\trender(){\n\t\treturn(\n\t\t\t&lt;div className=\"home--container\"&gt;\n\t\t\t\t&lt;h1&gt;Home Container&lt;\/h1&gt;\n\t\t\t&lt;\/div&gt;\n\t\t);\n\t}\n}\nexport default Home;<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>We&#8217;ll just add a &lt;h1&gt; for now, to see if our component is working. After this, we need to include our fresh home component into our index.js file, to make sure we&#8217;re launching the Home component instead of the previous App component (that we removed).<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ index.js\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport '.\/index.css';\nimport Home from '.\/components\/Home\/Home';\nReactDOM.render(&lt;Home \/&gt;, document.getElementById('root'));<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>If we navigate to our project now, we should be able to see our &#8216;Home Container&#8217; h1 element on the page. We&#8217;ll copy the code from our Home component also to our Auth components, to make sure they all work fine. So we have something to look at while we implement our React-Router.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Copy the Home.js code to the \/Auth\/Login.js and Register.js so we can start navigating through our different components. Just change the classname of the projects (obviously) and the title. So we can actually see when we change views. After that, import our Auth components into our index.js file as well to finish our project setup.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ index.js\n...\nimport Login    from '.\/components\/Auth\/Login';\nimport Register from '.\/components\/Auth\/Register';\n...<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-implementing-react-router\">Implementing React Router<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Now that we have all our components, let&#8217;s hook up React Router first, before we actually start implementing Firebase and Authentication. If you didn&#8217;t have react-router and react-router-dom installed in your project already, please go ahead and do so. If you have it, let&#8217;s edit our index.js file with react-router.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>First, import BrowserRouter from the react-router-dom:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Afterward, let&#8217;s create a Router component inside our index.js. This looks like a regular React Component like we did for Home and our Auth.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">class AppRouter extends React.Component{\n\trender(){\n\t\treturn(\n\t\t\t\/* ... router code here ... *\/\n\t\t);\n\t}\n}<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>We&#8217;ll add our Routercode in a second. For now, let&#8217;s switch out our &lt;Home \/&gt; component with our new &lt;AppRouter \/&gt; component to make sure we&#8217;re displaying the correct component at startup.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">ReactDOM.render(\n\t&lt;AppRouter \/&gt;, \n\tdocument.getElementById('root')\n);<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Ok, time to build our router inside our previously created AppRouter component! The&nbsp;Router component only accepts 1 child. So we&#8217;ll wrap everything in a parent-div:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ index.js\n...\nclass AppRouter extends React.Component{\n\trender(){\n\t\treturn(\n\t\t\t&lt;Router&gt;\n\t\t\t\t&lt;div className=\"app\"&gt;\n\t\t\t\t\t&lt;nav className=\"main-nav\"&gt;\n\t\t\t\t\t\t&lt;Link to=\"\/\"&gt;Home&lt;\/Link&gt;\n\t\t\t\t\t\t&lt;Link to=\"\/login\"&gt;Login&lt;\/Link&gt;\n\t\t\t\t\t\t&lt;Link to=\"\/register\"&gt;Register&lt;\/Link&gt;\n\t\t\t\t\t&lt;\/nav&gt;\n\t\t\t\t\t&lt;Switch&gt;\n\t\t\t\t\t\t&lt;Route path=\"\/\" exact component={Home} \/&gt;\n\t\t\t\t\t\t&lt;Route path=\"\/login\" exact component={Login} \/&gt;\n\t\t\t\t\t\t&lt;Route path=\"\/register\" exact component={Register} \/&gt;\n\t\t\t\t\t\t&lt;Route component={NoMatch} \/&gt;\n\t\t\t\t\t&lt;\/Switch&gt;\n\t\t\t\t&lt;\/div&gt;\n\t\t\t&lt;\/Router&gt;\n\t\t);\n\t}\n}\n...<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>We&#8217;ll use the &lt;nav&gt; element to display our navigation, so we&#8217;re able to navigate through our different views. Instead of &lt;a href=&#8221;&#8221;&gt; elements, we need to use &lt;Link to=&#8221;&#8221;&gt; elements. ReactRouter will automatically render these into normal &lt;a href=&#8221;&#8221;&gt; tags once it&#8217;s in the browser.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Also notice we&#8217;re using the Switch component to create our routes. Here we can say that if the URL of the page is equal to \/login, then render the Login component. Notice I use a {NoMatch} default Route, that we will be using for 404-pages. here&#8217;s the function for the NoMatch if you want to use this too. Place it right under our AppRouter component:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">const NoMatch = ({location}) =&gt; <div>No route match for {location.pathname}<\/div>;<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-implementing-firebase\">Implementing Firebase<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Before we can continue with our authentication, we&#8217;ll need to link firebase first. Head over to&nbsp;<a href=\"http:\/\/firebase.com\">firebase.com<\/a>&nbsp;and create a new database. After creating the new database, you should be able to see next screen: Click on the web icon to receive your web access tokens.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/firebase_01.jpg\" alt=\"\" class=\"wp-image-758\"\/><\/figure>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>This will open a popup with all the data you need. Copy all of it, because we&#8217;ll need it in a second. If you have not installed the firebase npm package yet, please go ahead and do so. If you have it already, create a new file named <code>firebase.js<\/code> in our \/src folder and paste the firebase snipped we just copied in there. Your firebase.js file will look like this:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ firebase.js\nimport firebase from 'firebase';\nconst config = {\n  apiKey: \"xxxxxxxxxx-xxxx-xxxx_xxxxxxxxxx_xxxxxxx\",\n  authDomain: \"app-name.firebaseapp.com\",\n  databaseURL: \"https:\/\/app-name.firebaseio.com\",\n  projectId: \"app-name\",\n  storageBucket: \"app-name.appspot.com\",\n  messagingSenderId: \"xxxxxxxxxxxx\"\n};\nfirebase.initializeApp(config);\nexport const provider = new firebase.auth.GoogleAuthProvider();\nexport const auth = firebase.auth();\nexport default firebase;<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Import Firebase from &#8216;firebase&#8217; at the top of this file to ease-up our future process. Because we&#8217;re using authentication through firebase as well, we&#8217;ll need a few more stuff. Add the firebase Provider and the firebase Auth into the file as well, just as in the example I posted before. At the end of our firebase.js file we need to export our firebase file so we can import it in all the files that will need to link with firebase.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>That&#8217;s actually all we need to link our React App with React-router to Firebase! Woohoow, I hope you could still follow along so far?<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-register-new-users-in-firebase\">Register new users in firebase<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>First things first, we can&#8217;t send messages without a user account. Because we need to know who send the message, so we know with who we&#8217;re chatting. Best to do authentication at the start, so we don&#8217;t need to manually edit all previous messages with a &#8216;sender_id&#8217; or something like that. Here&#8217;s the setup for our Register.js component:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ \/components\/Auth\/Register.js\nimport React from 'react';\nimport firebase from '..\/..\/firebase.js'\nimport { Link } from 'react-router-dom';\nimport '.\/Auth.css';\nimport Login from '.\/Login';\nclass Register extends React.Component{\n\tconstructor(props){\n\t\tsuper(props);\n\t\tthis.state = {\n\t\t\tusername: '',\n\t\t\temail: '',\n\t\t\tpassword: '',\n\t\t\terror: null\n\t\t}\n\t}\n\thandleChange = e =&gt; {\n\t\tthis.setState({[e.target.name]: e.target.value});\n\t}\n\thandleSubmit = e =&gt; {\n\t\te.preventDefault();\n\t\tconsole.log('Submitting form...');\n\t}\n\trender(){\n\t\tconst {email, username, password, error} = this.state;\n\t\treturn(\n\t\t\t&lt;div className=\"auth--container\"&gt;\n\t\t\t\t&lt;h1&gt;Register your account&lt;\/h1&gt;\n\t\t\t\t{error &amp;&amp; &lt;p className=\"error-message\"&gt;{error.message}&lt;\/p&gt;}\n\t\t\t\t&lt;form onSubmit={this.handleSubmit}&gt;\n\t\t\t\t\t&lt;label htmlFor=\"username\"&gt;Username&lt;\/label&gt;\n\t\t\t\t\t&lt;input type=\"text\" name=\"username\" id=\"username\" value={username} onChange={this.handleChange} \/&gt;\n\t\t\t\t\t&lt;label htmlFor=\"email\"&gt;Email address&lt;\/label&gt;\n\t\t\t\t\t&lt;input type=\"text\" name=\"email\" id=\"email\" value={email} onChange={this.handleChange} \/&gt;\n\t\t\t\t\t&lt;label htmlFor=\"password\"&gt;Choose a password&lt;\/label&gt;\n\t\t\t\t\t&lt;input\n\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\tid=\"password\"\n\t\t\t\t\t\tvalue={password}\n\t\t\t\t\t\tonChange={this.handleChange}\n\t\t\t\t\t\/&gt;\n\t\t\t\t\t&lt;button className=\"general-submit\" children=\"Get Started\" \/&gt;\n\t\t\t\t\t&lt;p&gt;Already have an account? &lt;Link className=\"login-btn\" to=\"\/login\"&gt;Login here&lt;\/Link&gt;&lt;\/p&gt;\n\t\t\t\t&lt;\/form&gt;\n\t\t\t&lt;\/div&gt;\n\t\t);\n\t}\n}\nexport default Register;<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>I&#8217;ll go over the file top to bottom. At the top, we import everything we need from React, firebase, and react-router. I am importing our Login component to easily switch to Login if our user already has an account. After that, we&#8217;ll create a constructor to set up our default state. We add an onChange handler for our inputfields (otherwise React doesn&#8217;t let us edit those fields) and an OnSubmit handler when our form will be submitted. For now, we only log &#8216;Submitting&#8230;&#8217; to make sure this is working. We&#8217;ll add our firebase code in a minute!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>After our functions we&#8217;ll add our jsx code inside the render() method. Our input fields need a name-attribute. Because this is what we target in our onChange function with <code>[e.target.name]<\/code> to change the current state. The value of the input-fields will be equal to their {state} value and we also add an onChange attribute that is equal to our handleChange() function.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p><strong>Update Firebase Authentication settings<\/strong><\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Before we can start building user registration and login, we need to activate authentication in our firebase project. Head over to firebase and select the &#8216;Authentication&#8217; tab from the left sidebar menu. In there, head over to the &#8216;inlog-method&#8217; tab and enable email\/password authentication.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/firebase_02.jpg\" alt=\"\" class=\"wp-image-760\"\/><\/figure>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/firebase_03.jpg\" alt=\"\" class=\"wp-image-761\"\/><\/figure>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Once done, and our \/register page is rendering correctly on the page, we can add our firebase code to register our users. Please change our onSubmit function to the following:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">handleSubmit = e =&gt; {\n    e.preventDefault();\n    const {email, username, password} = this.state;\n    firebase\n        .auth()\n\t.createUserWithEmailAndPassword(email, password)\n\t.then(() =&gt; {\n\t    const user = firebase.auth().currentUser;\n\t    user\n\t        .updateProfile({displayName: username})\n\t\t.then(() =&gt; {\n\t\t    this.props.history.push('\/');\n\t\t})\n\t\t.catch(error =&gt; {\n\t\t    this.setState({error});\n\t\t});\n        })\n    .catch(error =&gt; {\n        this.setState({error});\n    });\n}<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>First, we&#8217;ll declare all the variables from our state with ES6 destructuring like this: const { email, username, and password }. After that, we can do our Firebase call. This one access a lot of functions at once. firebase.auth() gives us access to the firebase authentication methods. Next we call &#8216;createUserWithEmailAndPassword(). I mean&#8230; ever seen an easier way to register users to your database? I don&#8217;t think so! The user&#8217;s password will be automatically hashed and we automatically get a user UID. I&#8217;m in love!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>The createUserWithEmailAndPassword() doesn&#8217;t allow to set a username all at once. So we&#8217;ll access the auth().currentUser directly after our registration and set the username ourselves. All Firebase calls are Promises, so we can hook them up with <code>.then(() =&gt; {...})<\/code> and <code>.catch(error =&gt; {...})<\/code> to catch all errors. We have an error-field in our state, which will be displayed on the page when we have errors. So after each catch, we&#8217;ll set the state to error. As you start playing with this, you will see that firebase gives us perfect error messages for everything that can go wrong.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-login-existing-users\">Login existing users<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>The firebase registration function automatically logs-in new users. That&#8217;s why we redirect back to the homepage after registration, because the user will be logged in automatically. You can turn this off in your firebase settings as well as adding extra&#8217;s like user email confirmations first. But I am not going to cover that in this post.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Let&#8217;s build something to login existing users, as for now, we lose our login-state when we navigate to different pages. We will add something to keep track of our state in this login function. The login code is actually exactly the same as our registration code. Except the handleSubmit function, this will look like this:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">handleSubmit = e =&gt; {\n    e.preventDefault();\n    const {email, password} = this.state;\n    firebase\n        .auth()\n        .signInWithEmailAndPassword(email, password)\n        .then(user =&gt; {\n            this.props.history.push('\/');\n        })\n        .catch(error =&gt; {\n            this.setState({error});\n        });\n}<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>This is the handleSubmit event in our Login.js file. All the rest is the same as our registration file. Except of course for login, we&#8217;ll only use email and password, no username. But even the handleSubmit code looks the same. We just switchour the&nbsp;createUserWithEmailAndPassword() function with the signInWithEmailAndPassword() function.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Now&#8230; How do we remain logged in while switching views? We&#8217;ll be updating our index.js file for this:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ index.js\n\/\/Import firebase package\nimport firebase, {auth, provider} from '.\/firebase.js'\n\/\/Add Contstructor to AppRouter component\nconstructor(props){\n    super(props);\n    this.state = {user: null}\n}\n\/\/Add componentDidMount lifecycle\ncomponentDidMount(){\n    auth.onAuthStateChanged(user =&gt; {\n    if(user){\n        this.setState({user});\n    }\n});<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>We need to include firebase at the top of our indexfile to be able to use Firebase functions. We also add a constructor to initialize our starting state. If our component mounts, we&#8217;ll check with firebase if our &#8216;userstate&#8217; (authstate in firebase) changed. If so, we check if we had a user, and we put the user in our React state again. So we&#8217;re actually pulling our Firebase state into our React state. (If you don&#8217;t logout in firebase, you will automatically be logged in when you visit the webpage again later on)<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-logout-the-current-user\">Logout the current user<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Let&#8217;s build a function to log our current users out of the application. We&#8217;ll just run a logout function when clicking on a link, so we don&#8217;t need navigation or create a new component for this. Add a log out link to the navigation:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">\/\/ element in index.js\n<nav className=\"main-nav\">\n    <Link to=\"\/\">Home<\/Link>\n    <Link to=\"\/login\">Login<\/Link>\n    <Link to=\"\/register\">Register<\/Link>\n    <button onClick={this.logOutUser}>Logout<\/button>\n<\/nav><\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>I just use a regular &lt;a&gt; element, with on onClick handler that will run our logout function. here is the Logout function:<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<pre><code class=\"language-javascript\">logOutUser = () =&gt; {\n    firebase.auth().signOut()\n        .then(window.location = \"\/\");\n}<\/code><\/pre>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>This will log out our user on firebase and afterwards hard-redirect to the homepage again. If you don&#8217;t want the hard-redirect, you can just change the React-state user to null again. But with the hard-redirect, our componentDidMount will check our actual firebase state and will see that no-one is logged in anymore. If the logout function throws an error, make sure to bind this new logOutUser function in our AppRouter constructor.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<h2 class=\"wp-block-heading\" id=\"h-what-s-next\">What&#8217;s next?<\/h2>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Phew&#8230; This already feels like a lot actually&#8230; I am going to split this post up into two parts. This part, that does the firebase hookup with authentication. And a second part, where we will be building the chatbox.<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>Let me know if my examples and code are not clear! I am both learning how to do React &amp; Firebase AND how to write decent blog posts at the same time. But hopefully, all works fine for you as well, and we can head over to <a href=\"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app-part-2\/\">PART 2: Building the chatbox<\/a>!<\/p>\n<\/div>\n\n<div class=\"default__block container-fluid lg\">\n<p>You can see a live demo of this application here: https:\/\/chat.weichie.com. You need to register an account first before you can see the chat. I did not put any effort into styling.<br><br>The GIT Repo of this project can be found here: <a href=\"https:\/\/github.com\/weichie\/react-firebase-chat\">https:\/\/github.com\/weichie\/react-firebase-chat<\/a>. Feel free to have a look around!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>I want to start creating apps with React, and what better way to do this than with a real-time application that other people can use? Making &#8216;real&#8217; stuff, gives me more motivation to start learning new things. I&#8217;ll be building a React Chat application with firebase and will blog along the way, to let you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":717,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[211],"tags":[262,263,264,265,162,266,267],"class_list":["post-1141","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-nl","tag-app-nl","tag-chat-nl","tag-chatbox-nl","tag-firebase-nl","tag-javascript-nl","tag-react-nl","tag-realtime-nl"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Firebase Chat app in React, React Router &amp; Authenticatie | Weichie<\/title>\n<meta name=\"description\" content=\"Wat is een betere manier om iets nieuws te leren dan met een realtime applicatie die andere mensen kunnen gebruiken?\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Firebase Chat with React, React Router &amp; Authentication | Weichie\" \/>\n<meta property=\"og:description\" content=\"What better way to learn something new than with a real-time application that other people can use? I&#039;ll be building a React Chat application with Firebase.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/\" \/>\n<meta property=\"og:site_name\" content=\"Weichie.com\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/weichiecom\/\" \/>\n<meta property=\"article:published_time\" content=\"2018-12-15T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-05T15:44:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/weichie.com\/wp-content\/uploads\/2020\/06\/weichie-general-og-image.jpg\" \/>\n<meta name=\"author\" content=\"weichie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Firebase Chat with React, React Router &amp; Authentication | Weichie\" \/>\n<meta name=\"twitter:description\" content=\"What better way to learn something new than with a real-time application that other people can use? I&#039;ll be building a React Chat application with Firebase.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/weichie.com\/wp-content\/uploads\/2020\/06\/weichie-general-og-image.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Geschreven door\" \/>\n\t<meta name=\"twitter:data1\" content=\"weichie\" \/>\n\t<meta name=\"twitter:label2\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/\"},\"author\":{\"name\":\"weichie\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#\\\/schema\\\/person\\\/36b4fff07382bc08a5c566728d9c579f\"},\"headline\":\"Building a Firebase Chat-app with React, React Router &#038; Authentication (part 1)\",\"datePublished\":\"2018-12-15T23:00:00+00:00\",\"dateModified\":\"2024-02-05T15:44:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/\"},\"wordCount\":2226,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/react-firebase-cover.jpg\",\"keywords\":[\"app\",\"Chat\",\"Chatbox\",\"firebase\",\"javascript\",\"react\",\"realtime\"],\"articleSection\":[\"Development\"],\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/\",\"url\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/\",\"name\":\"Firebase Chat app in React, React Router & Authenticatie | Weichie\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/react-firebase-cover.jpg\",\"datePublished\":\"2018-12-15T23:00:00+00:00\",\"dateModified\":\"2024-02-05T15:44:41+00:00\",\"description\":\"Wat is een betere manier om iets nieuws te leren dan met een realtime applicatie die andere mensen kunnen gebruiken?\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#primaryimage\",\"url\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/react-firebase-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/02\\\/react-firebase-cover.jpg\",\"width\":1458,\"height\":1458},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/blog\\\/react-firebase-chat-app\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/weichie.com\\\/nl\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Firebase Chat-app with React, React Router &#038; Authentication (part 1)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#website\",\"url\":\"https:\\\/\\\/weichie.com\\\/nl\\\/\",\"name\":\"Weichie.com\",\"description\":\"Digital Agency in Brussels &amp; New York\",\"publisher\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#organization\"},\"alternateName\":\"Weichie\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/weichie.com\\\/nl\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#organization\",\"name\":\"Weichie.com\",\"alternateName\":\"Weichie\",\"url\":\"https:\\\/\\\/weichie.com\\\/nl\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/Weichie_full.png\",\"contentUrl\":\"https:\\\/\\\/weichie.com\\\/wp-content\\\/uploads\\\/2023\\\/11\\\/Weichie_full.png\",\"width\":1181,\"height\":177,\"caption\":\"Weichie.com\"},\"image\":{\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/weichiecom\\\/\",\"https:\\\/\\\/www.instagram.com\\\/weichiecom\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/weichie\\\/\"],\"description\":\"A digital agency based in Brussels and New York. We create high-quality digital experiences for brands and help them promote their business through the online world! Specialised in websites, e-commerce, SEO and applications.\",\"email\":\"hello@weichie.com\",\"telephone\":\"+32 469 129 449\",\"legalName\":\"Weichie.com\",\"vatID\":\"0782.257.983\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"1\",\"maxValue\":\"10\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/weichie.com\\\/nl\\\/#\\\/schema\\\/person\\\/36b4fff07382bc08a5c566728d9c579f\",\"name\":\"weichie\",\"sameAs\":[\"https:\\\/\\\/weichie.com\"]}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Firebase Chat app in React, React Router & Authenticatie | Weichie","description":"Wat is een betere manier om iets nieuws te leren dan met een realtime applicatie die andere mensen kunnen gebruiken?","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/","og_locale":"nl_NL","og_type":"article","og_title":"Firebase Chat with React, React Router & Authentication | Weichie","og_description":"What better way to learn something new than with a real-time application that other people can use? I'll be building a React Chat application with Firebase.","og_url":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/","og_site_name":"Weichie.com","article_publisher":"https:\/\/www.facebook.com\/weichiecom\/","article_published_time":"2018-12-15T23:00:00+00:00","article_modified_time":"2024-02-05T15:44:41+00:00","og_image":[{"url":"https:\/\/weichie.com\/wp-content\/uploads\/2020\/06\/weichie-general-og-image.jpg","type":"","width":"","height":""}],"author":"weichie","twitter_card":"summary_large_image","twitter_title":"Firebase Chat with React, React Router & Authentication | Weichie","twitter_description":"What better way to learn something new than with a real-time application that other people can use? I'll be building a React Chat application with Firebase.","twitter_image":"https:\/\/weichie.com\/wp-content\/uploads\/2020\/06\/weichie-general-og-image.jpg","twitter_misc":{"Geschreven door":"weichie","Geschatte leestijd":"11 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#article","isPartOf":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/"},"author":{"name":"weichie","@id":"https:\/\/weichie.com\/nl\/#\/schema\/person\/36b4fff07382bc08a5c566728d9c579f"},"headline":"Building a Firebase Chat-app with React, React Router &#038; Authentication (part 1)","datePublished":"2018-12-15T23:00:00+00:00","dateModified":"2024-02-05T15:44:41+00:00","mainEntityOfPage":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/"},"wordCount":2226,"commentCount":0,"publisher":{"@id":"https:\/\/weichie.com\/nl\/#organization"},"image":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#primaryimage"},"thumbnailUrl":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/react-firebase-cover.jpg","keywords":["app","Chat","Chatbox","firebase","javascript","react","realtime"],"articleSection":["Development"],"inLanguage":"nl-NL","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/","url":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/","name":"Firebase Chat app in React, React Router & Authenticatie | Weichie","isPartOf":{"@id":"https:\/\/weichie.com\/nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#primaryimage"},"image":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#primaryimage"},"thumbnailUrl":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/react-firebase-cover.jpg","datePublished":"2018-12-15T23:00:00+00:00","dateModified":"2024-02-05T15:44:41+00:00","description":"Wat is een betere manier om iets nieuws te leren dan met een realtime applicatie die andere mensen kunnen gebruiken?","breadcrumb":{"@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#primaryimage","url":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/react-firebase-cover.jpg","contentUrl":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/02\/react-firebase-cover.jpg","width":1458,"height":1458},{"@type":"BreadcrumbList","@id":"https:\/\/weichie.com\/nl\/blog\/react-firebase-chat-app\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/weichie.com\/nl\/"},{"@type":"ListItem","position":2,"name":"Building a Firebase Chat-app with React, React Router &#038; Authentication (part 1)"}]},{"@type":"WebSite","@id":"https:\/\/weichie.com\/nl\/#website","url":"https:\/\/weichie.com\/nl\/","name":"Weichie.com","description":"Digital Agency in Brussels &amp; New York","publisher":{"@id":"https:\/\/weichie.com\/nl\/#organization"},"alternateName":"Weichie","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/weichie.com\/nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/weichie.com\/nl\/#organization","name":"Weichie.com","alternateName":"Weichie","url":"https:\/\/weichie.com\/nl\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/weichie.com\/nl\/#\/schema\/logo\/image\/","url":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/11\/Weichie_full.png","contentUrl":"https:\/\/weichie.com\/wp-content\/uploads\/2023\/11\/Weichie_full.png","width":1181,"height":177,"caption":"Weichie.com"},"image":{"@id":"https:\/\/weichie.com\/nl\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/weichiecom\/","https:\/\/www.instagram.com\/weichiecom\/","https:\/\/www.linkedin.com\/company\/weichie\/"],"description":"A digital agency based in Brussels and New York. We create high-quality digital experiences for brands and help them promote their business through the online world! Specialised in websites, e-commerce, SEO and applications.","email":"hello@weichie.com","telephone":"+32 469 129 449","legalName":"Weichie.com","vatID":"0782.257.983","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"1","maxValue":"10"}},{"@type":"Person","@id":"https:\/\/weichie.com\/nl\/#\/schema\/person\/36b4fff07382bc08a5c566728d9c579f","name":"weichie","sameAs":["https:\/\/weichie.com"]}]}},"_links":{"self":[{"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/posts\/1141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/comments?post=1141"}],"version-history":[{"count":0,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/posts\/1141\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/media\/717"}],"wp:attachment":[{"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/media?parent=1141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/categories?post=1141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/weichie.com\/nl\/wp-json\/wp\/v2\/tags?post=1141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}