{"id":107438,"date":"2025-04-30T11:59:00","date_gmt":"2025-04-30T11:59:00","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=107438"},"modified":"2025-05-15T10:21:30","modified_gmt":"2025-05-15T10:21:30","slug":"esp32-esp8266-firebase-web-app-sensor","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-web-app-sensor\/","title":{"rendered":"ESP32\/ESP8266: Firebase Web App to Display Sensor Readings (with Authentication)"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll create a Firebase Web App to display sensor readings saved on the Firebase Realtime Database. The sensor readings web page is protected with authentication using email and password. You&#8217;ll learn how to display data from the database and how to add authentication to your web app.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 NodeMCU Firebase Web App to Display Sensor Readings with Authentication\" class=\"wp-image-169603\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclgray\"><em>Updated 30 April 2025<\/em><\/p>\n\n\n\n<p>This article is Part 2 of this previous tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">ESP32\/ESP8266 Firebase: Send BME280 Sensor Readings to the Realtime Database<\/a>. Follow that tutorial first, before proceeding.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>In this tutorial (Part 2), you&#8217;ll create a web app to display the sensor readings saved on the Firebase Realtime Database (<a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">read this previous tutorial<\/a>).<\/p>\n\n\n\n<p>The following diagram shows a high-level overview of the project we&#8217;ll build\u2014programming the ESP32\/ESP8266 and setting up the Firebase Project was done in <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">Part 1<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"812\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Authentication-Overview-f.png?resize=750%2C812&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Firebase Web App Sensor Readings Authentication Project Overview\" class=\"wp-image-169590\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Authentication-Overview-f.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Authentication-Overview-f.png?resize=277%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 277w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Firebase hosts your web app over a global CDN using Firebase Hosting and provides an SSL certificate. You can access your web app from anywhere using the Firebase-generated domain name.<\/li>\n\n\n\n<li>When you first access the web app, you need to authenticate with an authorized email address and password. You already set up that user and the <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/#Set-Authentication-Methods\">authentication method in Part 1<\/a>.<\/li>\n\n\n\n<li>After authentication, you can access a web app page that shows the sensor readings saved on the realtime database. The<a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/#Set-up-Realtime-Database\"> realtime database was set up in Part 1<\/a>.<\/li>\n\n\n\n<li>Once you&#8217;re logged in, you can logout any time. The next time you access the app, you&#8217;ll need to login again.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before starting to create the Firebase Web App, you need to check the following prerequisites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a Firebase Project<\/h3>\n\n\n\n<p>You should have followed the following tutorial first:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">ESP32\/ESP8266 Firebase: Send BME280 Sensor Readings to the Realtime Database<\/a><\/li>\n<\/ul>\n\n\n\n<p>The ESP32\/ESP8266 must be running the code provided in that tutorial. The realtime database and authentication must also be set up as shown in the tutorial.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install Required Software<\/h3>\n\n\n\n<p>Before getting started, you need to install the required software to create the Firebase Web App. Here&#8217;s a list of the software you need to install (click on the links for instructions):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-web-app\/#install-vs-code\">Visual Studio Code<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-web-app\/#install-nodejs\">Node.JS LTS version<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-web-app\/#install-firebase-tools\">Install Firebase Tools<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1) Add an App to Your Firebase Project<\/h2>\n\n\n\n<p><strong>1)<\/strong> Go to your Firebase project Console and add an app to your project by clicking on the <strong>+Add app <\/strong>button. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"740\" height=\"198\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Add-App-to-Firebase-Project.png?resize=740%2C198&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Add App to Firebase Project\" class=\"wp-image-169592\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Add-App-to-Firebase-Project.png?w=740&amp;quality=100&amp;strip=all&amp;ssl=1 740w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Add-App-to-Firebase-Project.png?resize=300%2C80&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 740px) 100vw, 740px\" \/><\/figure><\/div>\n\n\n<p><strong>2)<\/strong> Select the web app icon.<\/p>\n\n\n\n<p><strong>3)<\/strong> Give your app a name. Then, check the box next to&nbsp;<strong>\u221a Also set up Firebase Hosting for this App<\/strong>. Click <strong>Register app<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"552\" height=\"601\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/add-firebase-to-web-app-example.png?resize=552%2C601&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Add Web App to Project Hosting\" class=\"wp-image-107458\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/add-firebase-to-web-app-example.png?w=552&amp;quality=100&amp;strip=all&amp;ssl=1 552w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/add-firebase-to-web-app-example.png?resize=276%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 276w\" sizes=\"(max-width: 552px) 100vw, 552px\" \/><\/figure><\/div>\n\n\n<p id=\"firebaseconfig-object\"><strong>4)<\/strong>&nbsp;Then, copy the&nbsp;<span class=\"rnthl rntliteral\">firebaseConfig<\/span>&nbsp;object and save it because you&#8217;ll need it later.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"210\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/app-firebase-config-object.png?resize=666%2C210&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"firebaseConfig\u00a0object configuration copy save\" class=\"wp-image-107462\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/app-firebase-config-object.png?w=666&amp;quality=100&amp;strip=all&amp;ssl=1 666w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/app-firebase-config-object.png?resize=300%2C95&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 666px) 100vw, 666px\" \/><\/figure><\/div>\n\n\n<p>After this, you can also access the&nbsp;<span class=\"rnthl rntliteral\">firebaseConfig<\/span>&nbsp;object if you go to your Project settings in your Firebase console.<\/p>\n\n\n\n<p><strong>5)<\/strong> Click&nbsp;<strong>Next<\/strong>&nbsp;on the proceeding steps, and finally on <strong>Continue to console<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2) Setting Up a Firebase Web App Project (VS Code)<\/h2>\n\n\n\n<p>Follow the next steps to create a Firebase Web App Project using VS Code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"create-project-folder\">1) Creating a Project Folder<\/h3>\n\n\n\n<p id=\"create-project-folder\"><strong>1)<\/strong> Create a folder on your computer where you want to save your Firebase project\u2014for example, <span class=\"rnthl rntliteral\"><em>Firebase-Project<\/em><\/span> on the Desktop.<\/p>\n\n\n\n<p><strong>2)<\/strong> Open VS Code. Go to <strong>File<\/strong> &gt; <strong>Open Folder&#8230;<\/strong> and select the folder you&#8217;ve just created.<\/p>\n\n\n\n<p><strong>3)<\/strong> Go to <strong>Terminal <\/strong>&gt; <strong>New Terminal<\/strong>. A new Terminal window should open on your project path.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"746\" height=\"163\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Firebase-Folder-Project.png?resize=746%2C163&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install Firebase Tools 2\" class=\"wp-image-106193\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Firebase-Folder-Project.png?w=746&amp;quality=100&amp;strip=all&amp;ssl=1 746w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Firebase-Folder-Project.png?resize=300%2C66&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 746px) 100vw, 746px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"firebase-login\">2) Firebase Login<\/h3>\n\n\n\n<p><strong>4)<\/strong> On the previous Terminal window, type the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>firebase <\/strong>login<\/code><\/pre>\n\n\n\n<p><strong>5)<\/strong> You&#8217;ll be asked to collect CLI usage and error reporting information. Enter &#8220;<strong>n<\/strong>&#8221; and press <strong>Enter<\/strong> to deny.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"397\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Login-Firebase-VS-Code.png?resize=750%2C397&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase VS Code Terminal Window\" class=\"wp-image-106194\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Login-Firebase-VS-Code.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Terminal-Window-Login-Firebase-VS-Code.png?resize=300%2C159&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>Note:<\/strong> If you are already logged in, it will show a message saying: &#8220;Already logged in as user@gmail.com&#8221;.<\/p>\n\n\n\n<p><strong>6)<\/strong> After this, it will pop up a new window on your browser to login into your Firebase account.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"648\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account.png?resize=750%2C648&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account\" class=\"wp-image-106195\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account.png?resize=300%2C259&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>7)<\/strong> Allow Firebase CLI to access your Google account.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"875\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account-2.png?resize=750%2C875&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI\" class=\"wp-image-106196\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account-2.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Login-Firebase-Account-2.png?resize=257%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 257w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>8)<\/strong> After this, Firebase CLI login should be successful. You can close the browser window.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"689\" height=\"454\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-CLI-Login-Successful.png?resize=689%2C454&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI Login Successful\" class=\"wp-image-106197\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-CLI-Login-Successful.png?w=689&amp;quality=100&amp;strip=all&amp;ssl=1 689w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-CLI-Login-Successful.png?resize=300%2C198&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 689px) 100vw, 689px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"init-project\">3) Initializing Web App Firebase Project<\/h3>\n\n\n\n<p><strong>9)<\/strong> After successfully login in, run the following command to start a Firebase project directory in the current folder.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>firebase <\/strong>init<\/code><\/pre>\n\n\n\n<p><strong>10)<\/strong> You&#8217;ll be asked if you want to initialize a Firebase project in the current directory. Enter <strong>Y<\/strong> and hit <strong>Enter<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"684\" height=\"187\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Start-Project-VS-Code.png?resize=684%2C187&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI firebase init\" class=\"wp-image-106199\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Start-Project-VS-Code.png?w=684&amp;quality=100&amp;strip=all&amp;ssl=1 684w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Start-Project-VS-Code.png?resize=300%2C82&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 684px) 100vw, 684px\" \/><\/figure><\/div>\n\n\n<p><strong>11)<\/strong> Then, use up and down arrows and the Space key to select the options. Select the following options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Realtime Database<\/strong>: Configure security rules file for Realtime Database and (optionally) provision default instance.  <\/li>\n\n\n\n<li><strong>Hosting<\/strong>: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys<\/li>\n<\/ul>\n\n\n\n<p>The selected options will show up with a green asterisk. Then, hit <strong>Enter<\/strong>. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"186\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/realtime-database-hosting-options.png?resize=750%2C186&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI configure directory\" class=\"wp-image-106239\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/realtime-database-hosting-options.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/realtime-database-hosting-options.png?resize=300%2C74&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>12)<\/strong> Select the option &#8220;Use an existing project&#8221;\u2014it should be highlighted in blue\u2014then, hit Enter.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"658\" height=\"228\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Project-Setup-VS-Code.png?resize=658%2C228&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project Setup VS Code\" class=\"wp-image-106201\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Project-Setup-VS-Code.png?w=658&amp;quality=100&amp;strip=all&amp;ssl=1 658w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/Firebase-Project-Setup-VS-Code.png?resize=300%2C104&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 658px) 100vw, 658px\" \/><\/figure><\/div>\n\n\n<p><strong>13)<\/strong> After that, select the Firebase project for this directory\u2014it should be <strong><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">the project created in this previous tutorial<\/a><\/strong>. In my case, it is called <span class=\"rnthl rntliteral\"><em>esp-<\/em><\/span>project. Then hit <strong>Enter<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"662\" height=\"174\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/select-firebase-project-VS-Code.png?resize=662%2C174&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Select Firebase Project on VS Code\" class=\"wp-image-170134\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/select-firebase-project-VS-Code.png?w=662&amp;quality=100&amp;strip=all&amp;ssl=1 662w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/select-firebase-project-VS-Code.png?resize=300%2C79&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 662px) 100vw, 662px\" \/><\/figure><\/div>\n\n\n<p><strong>14)<\/strong> Then, select the hosting options as shown below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What do you want to use as your public directory? Hit <strong>Enter <\/strong>to select <strong>public<\/strong>.<\/li>\n\n\n\n<li>Configure as a single-page app (rewrite urls to \/index.html)? <strong>No<\/strong><\/li>\n\n\n\n<li>Set up automatic builds and deploys with GitHub? <strong>No<\/strong><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"657\" height=\"277\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-hosting-setup-all-options.png?resize=657%2C277&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase initialization complete\" class=\"wp-image-106240\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-hosting-setup-all-options.png?w=657&amp;quality=100&amp;strip=all&amp;ssl=1 657w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-hosting-setup-all-options.png?resize=300%2C126&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 657px) 100vw, 657px\" \/><\/figure><\/div>\n\n\n<p><strong>15)<\/strong> Press <strong>Enter <\/strong>on the following question to select the default database security rules file: &#8220;<strong>What file should be used for Realtime Database Security Rules?<\/strong>&#8220;<\/p>\n\n\n\n<p><strong>16)<\/strong> The Firebase project should now be initialized successfully. Notice that VS Code created some essential files under your project folder.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"382\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-project-app-created-successfully.png?resize=750%2C382&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project Files Created successfully\" class=\"wp-image-106297\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-project-app-created-successfully.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/08\/firebase-project-app-created-successfully.png?resize=300%2C153&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The <span class=\"rnthl rntliteral\">index.html<\/span> file contains some HTML text to build a web page. For now, leave the default HTML text. The idea is to replace that with your own HTML text to build a custom web page for your needs. We&#8217;ll do that later in this tutorial.<\/p>\n\n\n\n<p><strong>17)<\/strong> To check if everything went as expected, run the following command on the VS Code Terminal window.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>firebase <\/strong>deploy<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"659\" height=\"322\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/firebase-first-deploy-test-app.png?resize=659%2C322&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase App First Deploy Testing\" class=\"wp-image-107463\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/firebase-first-deploy-test-app.png?w=659&amp;quality=100&amp;strip=all&amp;ssl=1 659w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/firebase-first-deploy-test-app.png?resize=300%2C147&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 659px) 100vw, 659px\" \/><\/figure><\/div>\n\n\n<p>You should get a <strong>Deploy complete!<\/strong> message and a URL to the Project Console and the Hosting URL.<\/p>\n\n\n\n<p><strong>18)<\/strong> Copy the hosting URL and paste it into a web browser window. You should see the following web page. You can access that web page from anywhere in the world.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"773\" height=\"495\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/firebase-hosting-complete.png?resize=773%2C495&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase test page hosting setup complete\" class=\"wp-image-106885\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/firebase-hosting-complete.png?w=773&amp;quality=100&amp;strip=all&amp;ssl=1 773w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/firebase-hosting-complete.png?resize=300%2C192&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/firebase-hosting-complete.png?resize=768%2C492&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 773px) 100vw, 773px\" \/><\/figure><\/div>\n\n\n<p>The web page you&#8217;ve seen previously is built with the HTML file placed in the <span class=\"rnthl rntliteral\">public<\/span> folder of your Firebase project. By changing the content of that file, you can create your own web app. That&#8217;s what we&#8217;re going to do in the next section.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3) Creating a Firebase Web App<\/h2>\n\n\n\n<p>Now that you&#8217;ve created a Firebase project app on VS Code, follow the next steps to customize the app to display the sensor readings on a login-protected web page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">index.html<\/h3>\n\n\n\n<p>Copy the following to your <span class=\"rnthl rntliteral\">index.html<\/span> file. This HTML file creates a simple web page that displays the readings saved on the <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-bme280-rtdb\/\">Realtime Database created in this previous project<\/a>.<\/p>\n\n\n\n<p>If you aren&#8217;t authenticated, it shows a login form. When you authenticate with an authorized user email and corresponding password, it shows the user interface with the sensor readings.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-html\">&lt;!-- Complete Project Details at: https:\/\/RandomNerdTutorials.com\/esp32-esp8266-firebase-web-app-sensor\/ --&gt;\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n  &lt;head&gt;\r\n    &lt;meta charset=&quot;utf-8&quot;&gt;\r\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;\r\n    &lt;title&gt;ESP IoT Firebase App&lt;\/title&gt;\r\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/use.fontawesome.com\/releases\/v5.7.2\/css\/all.css&quot; integrity=&quot;sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr&quot; crossorigin=&quot;anonymous&quot;&gt;\r\n    &lt;link rel=&quot;icon&quot; type=&quot;image\/png&quot; href=&quot;favicon.png&quot;&gt;\r\n    &lt;link rel=&quot;stylesheet&quot; type=&quot;text\/css&quot; href=&quot;style.css&quot;&gt;\r\n  &lt;\/head&gt;\r\n  &lt;body&gt;\r\n    &lt;!--TOP BAR--&gt;\r\n    &lt;div class=&quot;topnav&quot;&gt;\r\n      &lt;h1&gt;Sensor Readings App &lt;i class=&quot;fas fa-clipboard-list&quot;&gt;&lt;\/i&gt;&lt;\/h1&gt;\r\n    &lt;\/div&gt;\r\n\r\n    &lt;!--AUTHENTICATION BAR (USER DETAILS\/LOGOUT BUTTON)--&gt;\r\n    &lt;div id=&quot;authentication-bar&quot; style=&quot;display: none;&quot;&gt;\r\n      &lt;p&gt;&lt;span id=&quot;authentication-status&quot;&gt;User logged in&lt;\/span&gt;\r\n         &lt;span id=&quot;user-details&quot;&gt;USEREMAIL&lt;\/span&gt;\r\n         &lt;a href=&quot;#&quot; id=&quot;logout-link&quot;&gt;(logout)&lt;\/a&gt;\r\n      &lt;\/p&gt;\r\n    &lt;\/div&gt;\r\n\r\n    &lt;!--LOGIN FORM--&gt;\r\n    &lt;form id=&quot;login-form&quot; style=&quot;display: none;&quot;&gt;\r\n      &lt;div class=&quot;form-elements-container&quot;&gt;\r\n        &lt;label for=&quot;input-email&quot;&gt;&lt;b&gt;Email&lt;\/b&gt;&lt;\/label&gt;\r\n        &lt;input type=&quot;text&quot; placeholder=&quot;Enter Username&quot; id=&quot;input-email&quot; required&gt;\r\n        &lt;label for=&quot;input-password&quot;&gt;&lt;b&gt;Password&lt;\/b&gt;&lt;\/label&gt;\r\n        &lt;input type=&quot;password&quot; placeholder=&quot;Enter Password&quot; id=&quot;input-password&quot; required&gt;\r\n        &lt;button type=&quot;submit&quot; id=&quot;login-button&quot;&gt;Login&lt;\/button&gt;\r\n        &lt;p id=&quot;error-message&quot; style=&quot;color:red;&quot;&gt;&lt;\/p&gt;\r\n      &lt;\/div&gt;\r\n    &lt;\/form&gt;\r\n\r\n    &lt;!--CONTENT (SENSOR READINGS)--&gt;\r\n    &lt;div class=&quot;content-sign-in&quot; id=&quot;content-sign-in&quot; style=&quot;display: none;&quot;&gt;\r\n      &lt;div class=&quot;cards&quot;&gt;\r\n        &lt;!--TEMPERATURE--&gt;\r\n        &lt;div class=&quot;card&quot;&gt;\r\n          &lt;p&gt;&lt;i class=&quot;fas fa-thermometer-half&quot; style=&quot;color:#059e8a;&quot;&gt;&lt;\/i&gt; TEMPERATURE&lt;\/p&gt;\r\n          &lt;p&gt;&lt;span class=&quot;reading&quot;&gt;&lt;span id=&quot;temp&quot;&gt;&lt;\/span&gt; \u00b0C&lt;\/span&gt;&lt;\/p&gt;\r\n        &lt;\/div&gt;\r\n        &lt;!--HUMIDITY--&gt;\r\n        &lt;div class=&quot;card&quot;&gt;\r\n          &lt;p&gt;&lt;i class=&quot;fas fa-tint&quot; style=&quot;color:#00add6;&quot;&gt;&lt;\/i&gt; HUMIDITY&lt;\/p&gt;\r\n          &lt;p&gt;&lt;span class=&quot;reading&quot;&gt;&lt;span id=&quot;hum&quot;&gt;&lt;\/span&gt; %&lt;\/span&gt;&lt;\/p&gt;\r\n        &lt;\/div&gt;\r\n        &lt;!--PRESSURE--&gt;\r\n        &lt;div class=&quot;card&quot;&gt;\r\n          &lt;p&gt;&lt;i class=&quot;fas fa-angle-double-down&quot; style=&quot;color:#e1e437;&quot;&gt;&lt;\/i&gt; PRESSURE&lt;\/p&gt;\r\n          &lt;p&gt;&lt;span class=&quot;reading&quot;&gt;&lt;span id=&quot;pres&quot;&gt;&lt;\/span&gt; hPa&lt;\/span&gt;&lt;\/p&gt;\r\n        &lt;\/div&gt;\r\n      &lt;\/div&gt;\r\n    &lt;\/div&gt;\r\n    &lt;script type=&quot;module&quot; src=&quot;scripts\/auth.js&quot;&gt;&lt;\/script&gt;\r\n    &lt;script type=&quot;module&quot; src=&quot;scripts\/index.js&quot;&gt;&lt;\/script&gt;\r\n  &lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP-Firebase-Sensor-BME280\/index.html\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">How it Works<\/h4>\n\n\n\n<p>Let&#8217;s take a quick look at the HTML file, or skip to the next section.<\/p>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;head&gt;<\/span><\/span> of the HTML file, we must add all the required metadata.<\/p>\n\n\n\n<p>The title of the web page is <strong>ESP Firebase App<\/strong>, but you can change it in the following line.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;title&gt;ESP Firebase App&lt;\/title&gt;<\/code><\/pre>\n\n\n\n<p>The following line allows us to use <a href=\"https:\/\/fontawesome.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">fontawesome icons<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;link rel=\"stylesheet\" href=\"https:\/\/use.fontawesome.com\/releases\/v5.7.2\/css\/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\"&gt;<\/code><\/pre>\n\n\n\n<p>The next includes a <a href=\"https:\/\/github.com\/RuiSantosdotme\/build-web-servers-dl\/raw\/main\/favicon.zip\" target=\"_blank\" rel=\"noreferrer noopener\">favicon<\/a> in our web page.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;link rel=\"icon\" type=\"image\/png\" href=\"favicon.png\"&gt;<\/code><\/pre>\n\n\n\n<p>Finally, reference an external <span class=\"rnthl rntliteral\">style.css<\/span> file to format the HTML page.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"style.css\"&gt;<\/code><\/pre>\n\n\n\n<p>We&#8217;re done with the metadata. Now, let&#8217;s go to the HTML parts that are visible to the user\u2014go between the <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;body&gt;<\/span><\/span> and <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;\/body&gt;<\/span><\/span> tags.<\/p>\n\n\n\n<p>We create a top &#8220;navigation&#8221; bar with the name of our app and a small icon from fontawesome.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;div class=\"topnav\"&gt;\n  &lt;h1&gt;Sensor Readings App &lt;i class=\"fas fa-clipboard-list\"&gt;&lt;\/i&gt;&lt;\/h1&gt;\n&lt;\/div&gt;<\/code><\/pre>\n\n\n\n<p>The following lines create a bar with the details of the authenticated user (email). It also shows a logout link to log out the user. <\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;div id=\"authentication-bar\" style=\"display: none;\"&gt;\n  &lt;p&gt;&lt;span id=\"authentication-status\"&gt;User logged in&lt;\/span&gt;\n     &lt;span id=\"user-details\"&gt;USEREMAIL&lt;\/span&gt;\n     &lt;a href=\"\/\" id=\"logout-link\"&gt;(logout)&lt;\/a&gt;\n  &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n\n\n\n<p>First, we set the display style of all elements to <span class=\"rnthl rntliteral\">none<\/span>. We&#8217;ll hide and show content depending on whether the user is authenticated or not\u2014we&#8217;ll handle that using JavaScript.<\/p>\n\n\n\n<p>Next, the following lines create the login form with an input field for the email and an input field for the password:<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;form id=\"login-form\" style=\"display: none;\"&gt;  \n  &lt;div class=\"form-elements-container\"&gt;\n    &lt;label for=\"input-email\"&gt;&lt;b&gt;Email&lt;\/b&gt;&lt;\/label&gt;\n    &lt;input type=\"text\" placeholder=\"Enter Username\" id=\"input-email\" required&gt;\n  \n    &lt;label for=\"input-password\"&gt;&lt;b&gt;Password&lt;\/b&gt;&lt;\/label&gt;\n    &lt;input type=\"password\" placeholder=\"Enter Password\" id=\"input-password\" required&gt;\n          \n    &lt;button type=\"submit\" id=\"login-button\"&gt;Login&lt;\/button&gt;\n    &lt;p id=\"error-message\" style=\"color:red;\"&gt;&lt;\/p&gt;\n  &lt;\/div&gt;\n&lt;\/form&gt;<\/code><\/pre>\n\n\n\n<p>Inside the form, there&#8217;s also a paragraph to display an error message if the login fails.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;p id=\"error-message\" style=\"color:red;\"&gt;&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<p>Finally, we create a grid to display the sensor readings.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;!--CONTENT (SENSOR READINGS)--&gt;\n&lt;div class=\"content-sign-in\" id=\"content-sign-in\" style=\"display: none;\"&gt;\n  &lt;div class=\"cards\"&gt;\n    &lt;!--TEMPERATURE--&gt;\n    &lt;div class=\"card\"&gt;\n      &lt;p&gt;&lt;i class=\"fas fa-thermometer-half\" style=\"color:#059e8a;\"&gt;&lt;\/i&gt; TEMPERATURE&lt;\/p&gt;\n      &lt;p&gt;&lt;span class=\"reading\"&gt;&lt;span id=\"temp\"&gt;&lt;\/span&gt; &amp;deg;C&lt;\/span&gt;&lt;\/p&gt;\n    &lt;\/div&gt;\n    &lt;!--HUMIDITY--&gt;\n    &lt;div class=\"card\"&gt;\n      &lt;p&gt;&lt;i class=\"fas fa-tint\" style=\"color:#00add6;\"&gt;&lt;\/i&gt; HUMIDITY&lt;\/p&gt;\n      &lt;p&gt;&lt;span class=\"reading\"&gt;&lt;span id=\"hum\"&gt;&lt;\/span&gt; &amp;percnt;&lt;\/span&gt;&lt;\/p&gt;\n    &lt;\/div&gt;\n    &lt;!--PRESSURE--&gt;\n    &lt;div class=\"card\"&gt;\n      &lt;p&gt;&lt;i class=\"fas fa-angle-double-down\" style=\"color:#e1e437;\"&gt;&lt;\/i&gt; PRESSURE&lt;\/p&gt;\n      &lt;p&gt;&lt;span class=\"reading\"&gt;&lt;span id=\"pres\"&gt;&lt;\/span&gt; hPa&lt;\/span&gt;&lt;\/p&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/div&gt;<\/code><\/pre>\n\n\n\n<p>The places where we&#8217;ll insert the sensor readings have <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;span&gt;<\/span><\/span> tags with specific ids so that we can refer to those HTML elements using JavaScript and insert sensor readings saved in the database.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>temperature: <span class=\"rnthl rntliteral\">id = &#8220;temp&#8221;<\/span><\/li>\n\n\n\n<li>humidity: <span class=\"rnthl rntliteral\">id = &#8220;hum&#8221;<\/span><\/li>\n\n\n\n<li>pressure: <span class=\"rnthl rntliteral\">id = &#8220;pres&#8221;<\/span><\/li>\n<\/ul>\n\n\n\n<p>Finally, we need to add references to the external JavaScript files. For our application, we&#8217;ll create two JavaScript files: <span class=\"rnthl rntliteral\">auth.js<\/span> (that handles everything related to the authentication) and <span class=\"rnthl rntliteral\">index.js<\/span> that handles everything related to the UI. We&#8217;ll create those files inside a folder called <span class=\"rnthl rntliteral\">scripts<\/span> inside the <span class=\"rnthl rntliteral\">public<\/span> folder of our application.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;script src=\"scripts\/auth.js\"&gt;&lt;\/script&gt;\n&lt;script src=\"scripts\/index.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>Save the HTML file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">style.css<\/h3>\n\n\n\n<p>Inside the <span class=\"rnthl rntliteral\">public<\/span> folder create a file called <span class=\"rnthl rntliteral\">style.css<\/span>. To create the file, select the <span class=\"rnthl rntliteral\">public<\/span> folder, and then click on the <strong>+file<\/strong> icon at the top of the File Explorer. Call it <span class=\"rnthl rntliteral\">style.css<\/span>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"578\" height=\"277\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-CSS-File.png?resize=578%2C277&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Create CSS File VS Code\" class=\"wp-image-107545\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-CSS-File.png?w=578&amp;quality=100&amp;strip=all&amp;ssl=1 578w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-CSS-File.png?resize=300%2C144&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 578px) 100vw, 578px\" \/><\/figure><\/div>\n\n\n<p>Then, copy the following to the <span class=\"rnthl rntliteral\">style.css<\/span> file<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-CSS\">html {\r\n    font-family: Verdana, Geneva, Tahoma, sans-serif;\r\n    display: inline-block;\r\n    text-align: center;\r\n}\r\n\r\np {\r\n    font-size: 1.2rem; \r\n}\r\n\r\nbody {\r\n    margin: 0;\r\n}\r\n\r\n.topnav {\r\n    overflow: hidden;\r\n    background-color: #049faa;\r\n    color: white;\r\n    font-size: 1rem;\r\n    padding: 10px;\r\n}\r\n\r\n#authentication-bar{\r\n    background-color:mintcream;\r\n    padding-top: 10px;\r\n    padding-bottom: 10px;\r\n}\r\n\r\n#user-details{\r\n    color: cadetblue;\r\n}\r\n\r\n.content {\r\n    padding: 20px;\r\n}\r\n\r\n.card {\r\n    background-color: white;\r\n    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);\r\n    padding: 5%;\r\n}\r\n\r\n.cards {\r\n    max-width: 800px;\r\n    margin: 0 auto;\r\n    display: grid;\r\n    grid-gap: 2rem;\r\n    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n}\r\n\r\n.reading {\r\n    font-size: 1.4rem;\r\n}\r\n\r\nbutton {\r\n    background-color: #049faa;\r\n    color: white;\r\n    padding: 14px 20px;\r\n    margin: 8px 0;\r\n    border: none;\r\n    cursor: pointer;\r\n    border-radius: 4px;\r\n}\r\nbutton:hover {\r\n    opacity: 0.8;\r\n}\r\n\r\n.form-elements-container{\r\n    padding: 16px;\r\n    width: 250px;\r\n    margin: 0 auto;\r\n}\r\n\r\ninput[type=text], input[type=password] {\r\n    width: 100%;\r\n    padding: 12px 20px;\r\n    margin: 8px 0;\r\n    display: inline-block;\r\n    border: 1px solid #ccc;\r\n    box-sizing: border-box;\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP-Firebase-Sensor-BME280\/style.css\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>The CSS file includes some simple styles to make our webpage look better. We won&#8217;t discuss how CSS works in this tutorial.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">JavaScript Files<\/h3>\n\n\n\n<p>We&#8217;ll create two JavaScript files (<span class=\"rnthl rntliteral\">auth.js<\/span> and <span class=\"rnthl rntliteral\">index.js<\/span>) inside a <span class=\"rnthl rntliteral\">scripts<\/span> folder inside the <span class=\"rnthl rntliteral\">public<\/span> folder.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Select the <span class=\"rnthl rntliteral\">public<\/span> folder, then click on the <strong>+folder<\/strong> icon to create a new folder. Call <span class=\"rnthl rntliteral\">scripts<\/span> to that new folder.<\/li>\n\n\n\n<li>Then, select the <span class=\"rnthl rntliteral\">scripts<\/span> folder and click on the <strong>+file<\/strong> icon. Create a file called <span class=\"rnthl rntliteral\">auth.js<\/span>. Then, repeat the previous steps to create an <span class=\"rnthl rntliteral\">index.js<\/span>.<\/li>\n<\/ul>\n\n\n\n<p>The following image shows how your web app project folder structure should look.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"586\" height=\"288\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-Folder-File-Structure.png?resize=586%2C288&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project VS Code Folder File Structure\" class=\"wp-image-107546\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-Folder-File-Structure.png?w=586&amp;quality=100&amp;strip=all&amp;ssl=1 586w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/Firebase-Project-VS-Code-Folder-File-Structure.png?resize=300%2C147&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 586px) 100vw, 586px\" \/><\/figure><\/div>\n\n\n<h4 class=\"wp-block-heading\">auth.js<\/h4>\n\n\n\n<p>Now let&#8217;s implement user sign-in using Firebase authentication. We&#8217;ll implement sign-in using email and password.<\/p>\n\n\n\n<p>Copy the following to the <span class=\"rnthl rntliteral\">auth.js<\/span> file you created previously. <\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-javascript\">import { auth } from &quot;.\/index.js&quot;;\r\nimport { signInWithEmailAndPassword, signOut, onAuthStateChanged } from &quot;https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-auth.js&quot;;\r\n\r\ndocument.addEventListener(&quot;DOMContentLoaded&quot;, () =&gt; {\r\n  \/\/ Listen for auth status changes\r\n  onAuthStateChanged(auth, (user) =&gt; {\r\n    if (user) {\r\n      console.log(&quot;User logged in:&quot;, user.email);\r\n      setupUI(user);\r\n    } else {\r\n      console.log(&quot;User logged out&quot;);\r\n      setupUI(null);\r\n    }\r\n  });\r\n\r\n  \/\/ Login\r\n  const loginForm = document.querySelector('#login-form');\r\n  loginForm.addEventListener('submit', async (e) =&gt; {\r\n    e.preventDefault();\r\n    const email = loginForm['input-email'].value;\r\n    const password = loginForm['input-password'].value;\r\n    try {\r\n      await signInWithEmailAndPassword(auth, email, password);\r\n      loginForm.reset();\r\n      console.log(&quot;Logged in:&quot;, email);\r\n    } catch (error) {\r\n      document.getElementById(&quot;error-message&quot;).innerHTML = error.message;\r\n      console.error(&quot;Login error:&quot;, error.message);\r\n    }\r\n  });\r\n\r\n  \/\/ Logout\r\n  const logoutLink = document.querySelector('#logout-link');\r\n  logoutLink.addEventListener('click', async (e) =&gt; {\r\n    e.preventDefault();\r\n    try {\r\n      await signOut(auth);\r\n      console.log(&quot;User signed out&quot;);\r\n    } catch (error) {\r\n      console.error(&quot;Logout error:&quot;, error.message);\r\n    }\r\n  });\r\n});\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP-Firebase-Sensor-BME280\/auth.js\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Then, save the file. This file takes care of everything related to the login and logout of the user. Continue reading to learn how the code works, or skip to the next section.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Importing Modules<\/h4>\n\n\n\n<p>We start by importing the required modules. We import the <span class=\"rnthl rntliteral\">auth<\/span> authentication variable from the <span class=\"rnthl rntliteral\">index.js<\/span> file (we&#8217;ll take a look at it next) that is required to check whether the user is logged in or not.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>import { auth } from \".\/index.js\";<\/code><\/pre>\n\n\n\n<p>We also import all required Firebase modules.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>import { signInWithEmailAndPassword, signOut, onAuthStateChanged } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-auth.js\";<\/code><\/pre>\n\n\n\n<p><strong>Login<\/strong><\/p>\n\n\n\n<p>The following lines are responsible for logging in the user.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Login\nconst loginForm = document.querySelector('#login-form');\nloginForm.addEventListener('submit', async (e) =&gt; {\n  e.preventDefault();\n  const email = loginForm&#091;'input-email'].value;\n  const password = loginForm&#091;'input-password'].value;\n  try {\n    await signInWithEmailAndPassword(auth, email, password);\n    loginForm.reset();\n    console.log(\"Logged in:\", email);\n  } catch (error) {\n    document.getElementById(\"error-message\").innerHTML = error.message;\n    console.error(\"Login error:\", error.message);\n  }\n});<\/code><\/pre>\n\n\n\n<p>We create a variable that refers to the login form HTML element called <span class=\"rnthl rntliteral\">loginForm<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const loginForm = document.querySelector('#login-form');<\/code><\/pre>\n\n\n\n<p>If you go back to the <span class=\"rnthl rntliteral\">index.html<\/span> file, you can see that the form has the <span class=\"rnthl rntliteral\">login-form<\/span> id.<\/p>\n\n\n\n<p>We add an event listener of type <span class=\"rnthl rntliteral\">submit<\/span> to the form. This means that the subsequent instructions will run whenever the form is submitted.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>loginForm.addEventListener('submit', (e) =&gt; {<\/code><\/pre>\n\n\n\n<p>You can get the submitted data as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const email = loginForm&#091;'input-email'].value;\nconst password = loginForm&#091;'input-password'].value;<\/code><\/pre>\n\n\n\n<p>If you go back to the HTML file, you&#8217;ll see that the input fields contain the following ids: <span class=\"rnthl rntliteral\">input-email<\/span> and <span class=\"rnthl rntliteral\">input-password<\/span> for the email and password, respectively.<\/p>\n\n\n\n<p>Now that we have the inserted email and password, we can try to log in to Firebase. To do that, pass the user&#8217;s email address and password to the following method: <span class=\"rnthl rntliteral\">signInWithEmailAndPassword<\/span>:<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>try {\n  await signInWithEmailAndPassword(auth, email, password);<\/code><\/pre>\n\n\n\n<p>After logging in, we reset the form and print the user email in the console.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>loginForm.reset();\nconsole.log(\"Logged in:\", email);<\/code><\/pre>\n\n\n\n<p>In case there is an error signing in, we catch the error message, and display it on the <span class=\"rnthl rntliteral\">error-message<\/span> HTML element (a paragraph below the form).<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>} catch (error) {\n  document.getElementById(\"error-message\").innerHTML = error.message;\n  console.error(\"Login error:\", error.message);\n}<\/code><\/pre>\n\n\n\n<p><strong>Logout<\/strong><\/p>\n\n\n\n<p>The following snippet is responsible for logging out the user.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Logout\nconst logoutLink = document.querySelector('#logout-link');\nlogoutLink.addEventListener('click', async (e) =&gt; {\n  e.preventDefault();\n  try {\n    await signOut(auth);\n    console.log(\"User signed out\");\n  } catch (error) {\n    console.error(\"Logout error:\", error.message);\n  }\n});<\/code><\/pre>\n\n\n\n<p>When the user is logged in, a logout link is visible in the authentication bar. That link has the <span class=\"rnthl rntliteral\">logout-link<\/span> id (see in the HTML file). So, first, we create a variable called <span class=\"rnthl rntliteral\">logout<\/span> that refers to the logout link.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const logout = document.querySelector('#logout-link');<\/code><\/pre>\n\n\n\n<p>Then, we add an event listener of type <span class=\"rnthl rntliteral\">click<\/span>. This means the subsequent instructions will run whenever you click on the logout link.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>logout.addEventListener('click', (e) =&gt; {<\/code><\/pre>\n\n\n\n<p>When the button is clicked, we sign out the user using the <span class=\"rnthl rntliteral\">signOut<\/span> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>try {\n  await signOut(auth);\n  console.log(\"User signed out\");\n} catch (error) {\n  console.error(\"Logout error:\", error.message);\n}<\/code><\/pre>\n\n\n\n<p><strong>Auth State Changes<\/strong><\/p>\n\n\n\n<p>To keep track of the user authentication state\u2014to know if the user is logged in or logged out, there is a method called <span class=\"rnthl rntliteral\">onAuthSateChanged<\/span> that allows you to receive an event whenever the authentication state changes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>document.addEventListener(\"DOMContentLoaded\", () =&gt; {\n  \/\/ Listen for auth status changes\n  onAuthStateChanged(auth, (user) =&gt; {\n    if (user) {\n      console.log(\"User logged in:\", user.email);\n      setupUI(user);\n    } else {\n      console.log(\"User logged out\");\n      setupUI(null);\n    }\n  });<\/code><\/pre>\n\n\n\n<p>If the user returned is <span class=\"rnthl rntliteral\">null<\/span>, the user is currently signed out. Otherwise, it is currently signed in.<\/p>\n\n\n\n<p>In both scenarios, we print the current user state to the console and call the <span class=\"rnthl rntliteral\">setupUI()<\/span> function. We haven&#8217;t created that function yet (we&#8217;ll create it in the next section), but it will be responsible for handling the user interface accordingly to the authentication state.<\/p>\n\n\n\n<p>When the user is logged in, we pass the <span class=\"rnthl rntliteral\">user<\/span> as an argument to the <span class=\"rnthl rntliteral\">setupUI()<\/span> function. In this case, we&#8217;ll display the complete user interface to show the sensor readings, as you&#8217;ll see later.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>if (user) {\n  console.log(\"User logged in:\", user.email);\n  setupUI(user);<\/code><\/pre>\n\n\n\n<p>If the user is logged out, we call the <span class=\"rnthl rntliteral\">setupUI()<\/span> function with the <span class=\"rnthl rntliteral\">null<\/span> argument. In that scenario, we&#8217;ll simply display a message informing that the user is logged out and doesn&#8217;t have access to the interface (as we&#8217;ll see later).<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>} else {\n  console.log(\"User logged out\");\n  setupUI(null);\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">index.js<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">index.js<\/span> file handles the UI &#8211; it shows the right content depending on the user&#8217;s authentication status. When the user is logged in, this file gets new readings from the database whenever there&#8217;s a change.<\/p>\n\n\n\n<p>Copy the following to the <span class=\"rnthl rntliteral\">index.js<\/span> file. <\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-javascript\">import { initializeApp } from &quot;https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-app.js&quot;;\r\nimport { getAuth } from &quot;https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-auth.js&quot;;\r\nimport { getDatabase, ref, onValue } from &quot;https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-database.js&quot;;\r\n\r\n\/\/ Firebase configuration\r\nconst firebaseConfig = {\r\n    apiKey: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    authDomain: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    databaseURL: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    projectId: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    storageBucket: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    messagingSenderId: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;,\r\n    appId: &quot;REPLACE_WITH_YOUR_Firebase_CONFIGURATION&quot;\r\n};\r\n\r\n\/\/ Initialize Firebase\r\nconst app = initializeApp(firebaseConfig);\r\nconst auth = getAuth(app);\r\nconst database = getDatabase(app);\r\n\r\n\/\/ Export auth for use in auth.js\r\nexport { auth };\r\n\r\n\/\/ UI Elements\r\nconst loginElement = document.querySelector('#login-form');\r\nconst contentElement = document.querySelector(&quot;#content-sign-in&quot;);\r\nconst userDetailsElement = document.querySelector('#user-details');\r\nconst authBarElement = document.querySelector(&quot;#authentication-bar&quot;);\r\nconst tempElement = document.getElementById(&quot;temp&quot;);\r\nconst humElement = document.getElementById(&quot;hum&quot;);\r\nconst presElement = document.getElementById(&quot;pres&quot;);\r\n\r\n\/\/ Manage Login\/Logout UI\r\nconst setupUI = (user) =&gt; {\r\n  if (user) {\r\n    \/\/ Toggle UI elements\r\n    loginElement.style.display = 'none';\r\n    contentElement.style.display = 'block';\r\n    authBarElement.style.display = 'block';\r\n    userDetailsElement.style.display = 'block';\r\n    userDetailsElement.innerHTML = user.email;\r\n\r\n    \/\/ Database paths\r\n    const uid = user.uid;\r\n    const dbPathTemp = `UsersData\/${uid}\/temperature`;\r\n    const dbPathHum = `UsersData\/${uid}\/humidity`;\r\n    const dbPathPres = `UsersData\/${uid}\/pressure`;\r\n\r\n    \/\/ Database references\r\n    const dbRefTemp = ref(database, dbPathTemp);\r\n    const dbRefHum = ref(database, dbPathHum);\r\n    const dbRefPres = ref(database, dbPathPres);\r\n\r\n    \/\/ Update page with new readings\r\n    onValue(dbRefTemp, (snap) =&gt; {\r\n      tempElement.innerText = snap.val()?.toFixed(2) ?? &quot;N\/A&quot;;\r\n    });\r\n\r\n    onValue(dbRefHum, (snap) =&gt; {\r\n      humElement.innerText = snap.val()?.toFixed(2) ?? &quot;N\/A&quot;;\r\n    });\r\n\r\n    onValue(dbRefPres, (snap) =&gt; {\r\n      presElement.innerText = snap.val()?.toFixed(2) ?? &quot;N\/A&quot;;\r\n    });\r\n  } else {\r\n    \/\/ Toggle UI elements\r\n    loginElement.style.display = 'block';\r\n    authBarElement.style.display = 'none';\r\n    userDetailsElement.style.display = 'none';\r\n    contentElement.style.display = 'none';\r\n  }\r\n};\r\n\r\n\/\/ Expose setupUI to global scope for auth.js\r\nwindow.setupUI = setupUI;\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP-Firebase-Sensor-BME280\/index.js\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the next section.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Importing Firebase Modules<\/h4>\n\n\n\n<p>We start by importing the required Firebase modules.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-app.js\";\nimport { getAuth } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-auth.js\";\nimport { getDatabase, ref, onValue } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.0\/firebase-database.js\";<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Firebase Configuration Object<\/h4>\n\n\n\n<p>Modify the following lines with your Firebase Configuration object you got in the previous steps.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const firebaseConfig = {\n  apiKey: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  authDomain: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  databaseURL: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  projectId: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  storageBucket: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  messagingSenderId: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\",\n  appId: \"REPLACE_WITH_YOUR_Firebase_CONFIGURATION\"\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize Firebase App<\/h4>\n\n\n\n<p>The following line initializes the Firebase App using the provided <span class=\"rnthl rntliteral\">firebaseConfig<\/span> object.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const app = initializeApp(firebaseConfig);<\/code><\/pre>\n\n\n\n<p>Then, create an Authentication instance (<span class=\"rnthl rntliteral\">auth<\/span>) tied to the initialized Firebase app (<span class=\"rnthl rntliteral\">app<\/span>). The <span class=\"rnthl rntliteral\">getAuth<\/span> function from the Firebase Auth module sets up the authentication service for user management (login, logout, etc.).<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const auth = getAuth(app);<\/code><\/pre>\n\n\n\n<p>Create a Firebase Realtime Database instance called <span class=\"rnthl rntliteral\">database<\/span> tied to your Firebase App (<span class=\"rnthl rntliteral\">app<\/span>).<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const database = getDatabase(app);<\/code><\/pre>\n\n\n\n<p>Then, we export the <span class=\"rnthl rntliteral\">auth<\/span> instance so it can be imported and used in other JavaScript files (in <span class=\"rnthl rntliteral\">auth.js<\/span> like we&#8217;ve seen previously).<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>export { auth };<\/code><\/pre>\n\n\n\n<p><strong>Getting HTML Elements<\/strong><\/p>\n\n\n\n<p>Create variables to refer to several elements on the UI interface by referring to their ids. To identify these elements, we recommend that you take a look at the HTML file provided and find the elements with the referenced ids.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ UI Elements\nconst loginElement = document.querySelector('#login-form');\nconst contentElement = document.querySelector(\"#content-sign-in\");\nconst userDetailsElement = document.querySelector('#user-details');\nconst authBarElement = document.querySelector(\"#authentication-bar\");\nconst tempElement = document.getElementById(\"temp\");\nconst humElement = document.getElementById(\"hum\");\nconst presElement = document.getElementById(\"pres\");<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">loginElement<\/span> corresponds to the login form. The <span class=\"rnthl rntliteral\">contentElement<\/span> corresponds to the section of the web page that is visible when the user is logged in (that shows the sensor readings). The <span class=\"rnthl rntliteral\">userDetailsElement<\/span> corresponds to a section that will display the email of the logged in user. The <span class=\"rnthl rntliteral\">auhtBarElement<\/span> corresponds to the authentication bar that shows the current user status, the email of the authenticated user and the logout link.<\/p>\n\n\n\n<p><strong>sertupUI() Function<\/strong><\/p>\n\n\n\n<p>Then, we create the <span class=\"rnthl rntliteral\">setupUI()<\/span> function that will handle the UI according to the state of the user authentication.<\/p>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">auth.js<\/span> file, we called the <span class=\"rnthl rntliteral\">setupUI()<\/span> function with the <span class=\"rnthl rntliteral\">user<\/span> argument <span class=\"rnthl rntliteral\">setupUI(user)<\/span> if the user is logged in; or the function with the <span class=\"rnthl rntliteral\">null<\/span> argument when the user is logged out.<\/p>\n\n\n\n<p>So, let&#8217;s check what happens when the user is logged in.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>if (user) {<\/code><\/pre>\n\n\n\n<p>We define which parts of the UI should be visible or invisible. When the user is logged in, we want to hide the login form. To hide an element, we can set the display style to <span class=\"rnthl rntliteral\">none<\/span>. <\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>loginElement.style.display = 'none';<\/code><\/pre>\n\n\n\n<p>We show the authentication bar (that shows the user details and the logout link). To do that, we can set its display style to <span class=\"rnthl rntliteral\">block<\/span>. We also want the web page&#8217;s main content with the sensor readings to be visible.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>contentElement.style.display = 'block';\nauthBarElement.style.display ='block';<\/code><\/pre>\n\n\n\n<p>Finally, we can get the logged in user email with <span class=\"rnthl rntliteral\">user.email<\/span> and display it in the <span class=\"rnthl rntliteral\">userDetailsElement<\/span> section as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>userDetailsElement.innerHTML = user.email;<\/code><\/pre>\n\n\n\n<p><strong>User UID and Database Paths<\/strong><\/p>\n\n\n\n<p>After we have a logged-in user, we can get its UID with <span class=\"rnthl rntliteral\">user.uid<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const uid = user.uid;<\/code><\/pre>\n\n\n\n<p>After getting the user UID, we create variables to refer to the database paths where we save the data.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const dbPathTemp = `UsersData\/${uid}\/temperature`;\nconst dbPathHum = `UsersData\/${uid}\/humidity`;\nconst dbPathPres = `UsersData\/${uid}\/pressure`;<\/code><\/pre>\n\n\n\n<p>Then, we create database references to those paths.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Database references\nconst dbRefTemp = ref(database, dbPathTemp);\nconst dbRefHum = ref(database, dbPathHum);\nconst dbRefPres = ref(database, dbPathPres);<\/code><\/pre>\n\n\n\n<p><strong>Display Sensor Readings<\/strong><\/p>\n\n\n\n<p>The following lines get the new sensor readings whenever there&#8217;s a change in the database and update the corresponding HTML elements with the new values. It also formats the values to use two decimal places, or it returns <span class=\"rnthl rntliteral\">N\/A<\/span> if the value is missing.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Update page with new readings\nonValue(dbRefTemp, (snap) =&gt; {\n  tempElement.innerText = snap.val()?.toFixed(2) ?? \"N\/A\";\n });\n\nonValue(dbRefHum, (snap) =&gt; {\n  humElement.innerText = snap.val()?.toFixed(2) ?? \"N\/A\";\n});\n\nonValue(dbRefPres, (snap) =&gt; {\n  presElement.innerText = snap.val()?.toFixed(2) ?? \"N\/A\";\n});<\/code><\/pre>\n\n\n\n<p><strong>Logged Out UI<\/strong><\/p>\n\n\n\n<p>The following snippet handles the UI when the user logs out. We want to hide the authentication bar and the main webpage content (sensor readings) and show the login form.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>} else {\n  \/\/ Toggle UI elements\n  loginElement.style.display = 'block';\n  authBarElement.style.display = 'none';\n  userDetailsElement.style.display = 'none';\n  contentElement.style.display = 'none';\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Expose the setupUI function<\/h4>\n\n\n\n<p>Finally, the following line makes the <span class=\"rnthl rntliteral\">setupUI<\/span> function globally accessible by assigning it to the <span class=\"rnthl rntliteral\">window<\/span> object (the <span class=\"rnthl rntliteral\">window<\/span> object is a global object in a browser that is accessible from any JavaScript file). Basically, this ensures that the other Javascript file (<span class=\"rnthl rntliteral\">auth.js<\/span>) can use the <span class=\"rnthl rntliteral\">setupUI<\/span> function to update the UI when the user logs in or out.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>window.setupUI = setupUI;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Favicon File<\/h3>\n\n\n\n<p>To display a favicon in your web app, you need to move the picture you want to use as favicon to the <span class=\"rnthl rntliteral\">public<\/span> folder. The picture should be called favicon.png. You can simply drag the favicon file from your computer into the <span class=\"rnthl rntliteral\">public<\/span> folder in VS Code.<\/p>\n\n\n\n<p>We&#8217;re using the following icon as a favicon for our web app:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/RuiSantosdotme\/build-web-servers-dl\/raw\/main\/favicon.zip\" target=\"_blank\" rel=\"noreferrer noopener\">favicon.png<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Deploy your App<\/h3>\n\n\n\n<p>After saving the HTML, CSS, and JavaScript files, deploy your app on VS Code by running the following command in the Terminal window.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>firebase<\/strong> deploy<\/code><\/pre>\n\n\n\n<p>The Terminal should display something as follows:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"724\" height=\"312\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Deploy-Firebase-App-VS-Code-1.png?resize=724%2C312&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Deploy Firebase Web App\" class=\"wp-image-107548\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Deploy-Firebase-App-VS-Code-1.png?w=724&amp;quality=100&amp;strip=all&amp;ssl=1 724w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Deploy-Firebase-App-VS-Code-1.png?resize=300%2C129&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 724px) 100vw, 724px\" \/><\/figure><\/div>\n\n\n<p>Firebase offers a free hosting service to serve your assets and web apps. Then, you can access your web app from anywhere.<\/p>\n\n\n\n<p>You can use the Hosting URL provided to access your web app from anywhere.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>Congratulations! You successfully deployed your app. It is now hosted on a global CDN using Firebase hosting. You can access your web app from anywhere in the Hosting URL provided. In my case, it is <span class=\"rnthl rntliteral\">https:\/\/esp-firebase-demo.web.app<\/span>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"552\" height=\"450\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Sensor-Readings-Firebase-App.png?resize=552%2C450&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Sensor Readings Firebase Web App\" class=\"wp-image-107519\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Sensor-Readings-Firebase-App.png?w=552&amp;quality=100&amp;strip=all&amp;ssl=1 552w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/10\/ESP32-ESP8266-Sensor-Readings-Firebase-App.png?resize=300%2C245&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 552px) 100vw, 552px\" \/><\/figure><\/div>\n\n\n<p>The web app is responsive, and you can access it using your smartphone, computer, or tablet.<\/p>\n\n\n\n<p class=\"rntbox rntclgray\"><strong>Troubleshooting<\/strong>: if you don&#8217;t see the web app web page, you may need to hard refresh your web browser to clear the cache.<\/p>\n\n\n\n<p>Insert the email and password of the authorized user you added in the Firebase Authentication methods. After that, you can access the latest sensor readings.<\/p>\n\n\n\n<p>Go to your project&#8217;s Firebase console&nbsp;<strong>Hosting<\/strong>&nbsp;tab. You can see your app domains, deploy history, and you can even roll back to previous versions of your app.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"349\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Firebase-Hosting-History.jpg?resize=750%2C349&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Web App Deploy History and Domains\" class=\"wp-image-169598\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Firebase-Hosting-History.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/Firebase-Hosting-History.jpg?resize=300%2C140&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned how to create a Firebase Web App with login\/logout authentication that displays sensor readings. The sensor readings are saved on the realtime database. The database is protected using database rules (that you&#8217;ve already set up in the previous tutorial).<\/p>\n\n\n\n<p>You can apply what you learned here to display any other type of data, and you can change the files in the <span class=\"rnthl rntliteral\">public<\/span> folder to add different functionalities and features to your project.<\/p>\n\n\n\n<p>If you want to learn more about Firebase, we recommend taking a look at our eBook, exclusively dedicated to this subject:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/firebase-esp32-esp8266-ebook\/\">Firebase Web App with ESP32 and ESP8266<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p>We have other resources related to ESP32 and ESP8266 that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/home-automation-using-esp8266\/\">Home Automation using ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\">Build Web Servers with ESP32 and ESP8266<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll create a Firebase Web App to display sensor readings saved on the Firebase Realtime Database. The sensor readings web page is protected with authentication using email &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32\/ESP8266: Firebase Web App to Display Sensor Readings (with Authentication)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-web-app-sensor\/#more-107438\" aria-label=\"Read more about ESP32\/ESP8266: Firebase Web App to Display Sensor Readings (with Authentication)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":169603,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-107438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/12\/ESP32-ESP8266-Firebase-Web-App-Sensor-Readings-Authentication.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=107438"}],"version-history":[{"count":32,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107438\/revisions"}],"predecessor-version":[{"id":170139,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107438\/revisions\/170139"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/169603"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=107438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=107438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=107438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}