{"id":107976,"date":"2025-07-02T13:21:02","date_gmt":"2025-07-02T13:21:02","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=107976"},"modified":"2026-05-09T20:57:12","modified_gmt":"2026-05-09T20:57:12","slug":"esp32-cam-display-pictures-firebase-web-app","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cam-display-pictures-firebase-web-app\/","title":{"rendered":"ESP32-CAM: Display Pictures in Firebase Web App"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll create a Firebase Web App to display the last picture taken with an ESP32-CAM saved in the Firebase Storage. The Web App also shows the date and time that the last photo was taken. The web app is freely hosted on Firebase servers, and you can access it from anywhere.<\/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\/2022\/01\/ESP32-CAM-Firebase-Web-App.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Display Pictures in Firebase Web App\" class=\"wp-image-173171\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Web-App.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Web-App.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Web-App.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Web-App.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclgray\"><em>Updated  May 9, 2026.<\/em><\/p>\n\n\n\n<p>This article is Part 2 of this previous tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/\">ESP32-CAM Save Picture in Firebase Storage<\/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 last picture taken with the ESP32-CAM and saved in the Firebase Storage (see this <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/\">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-CAM and setting up the Firebase Project with Storage was done in Part 1. <\/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=\"616\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Firebase-Storage-Web-App-Project-Overview.png?resize=750%2C616&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Firebase Storage Project Overview\" class=\"wp-image-108009\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Firebase-Storage-Web-App-Project-Overview.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Firebase-Storage-Web-App-Project-Overview.png?resize=300%2C246&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" 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>The web application displays the last picture saved on Firebase Storage in the <span class=\"rnthl rntliteral\">data\/photo.jpg<\/span> path.<\/li>\n\n\n\n<li>It also displays info about when the picture was taken (date and time).<\/li>\n\n\n\n<li>If the web page is open, and meanwhile, there&#8217;s a new picture, you need to press the Refresh button, so that it gets the new picture from the storage path.<\/li>\n\n\n\n<li>Later, you can update the web app to do this automatically. For example, you can save the time the last picture was taken to <a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-realtime-database\/\">Firebase Realtime Database (RTDB)<\/a>. You can then, detect changes on the database, and refresh the web page as needed to display the last picture (we may cover this in a future, more advanced tutorial).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before you start creating 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-cam-save-picture-firebase-storage\/\">ESP32-CAM Save Picture in Firebase Storage<\/a><\/li>\n<\/ul>\n\n\n\n<p>The ESP32-CAM must be running the code provided in that tutorial so that there&#8217;s a picture saved in Firebase Storage. The Firebase Storage must be set up as shown in the tutorial.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing 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\" id=\"add-app-to-project\">1) 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 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\" 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>Hosting<\/strong>: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys<\/li>\n\n\n\n<li><strong>Storage<\/strong>: Configure a security rules file for Cloud Storage<\/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=\"180\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/create-firebase-project-with-storage.png?resize=750%2C180&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI firebase init\" class=\"wp-image-107977\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/create-firebase-project-with-storage.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/create-firebase-project-with-storage.png?resize=300%2C72&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 <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/\" title=\"\">the project created in Part 1<\/a> of this tutorial\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=\"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>13)<\/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>14)<\/strong> Then, press Enter on the following question to select the default file for storage rules.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What file should be used for Storage Rules?(<strong>storage.rules<\/strong>). Hit <strong>Enter<\/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=\"683\" height=\"68\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Project-Setup-Firebase-Storage-Rules.png?resize=683%2C68&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Login Firebase Account allow Firebase CLI firebase init\" class=\"wp-image-108012\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Project-Setup-Firebase-Storage-Rules.png?w=683&amp;quality=100&amp;strip=all&amp;ssl=1 683w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Project-Setup-Firebase-Storage-Rules.png?resize=300%2C30&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/figure><\/div>\n\n\n<p><strong>15)<\/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=\"595\" height=\"316\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-Firebase-Web-App-with-Storage-Files-on-VS-Code.png?resize=595%2C316&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project with Storage Files Created successfully\" class=\"wp-image-173128\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-Firebase-Web-App-with-Storage-Files-on-VS-Code.png?w=595&amp;quality=100&amp;strip=all&amp;ssl=1 595w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-Firebase-Web-App-with-Storage-Files-on-VS-Code.png?resize=300%2C159&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 595px) 100vw, 595px\" \/><\/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 create a custom web page for your needs. We&#8217;ll do that later in this tutorial.<\/p>\n\n\n\n<p><strong>16)<\/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\n<p>It will ask you if you want to set a new role. Hit Enter to accept.<\/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=\"713\" height=\"384\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/deploy-firebase-project.png?resize=713%2C384&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase App First Deploy Testing\" class=\"wp-image-170137\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/deploy-firebase-project.png?w=713&amp;quality=100&amp;strip=all&amp;ssl=1 713w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/02\/deploy-firebase-project.png?resize=300%2C162&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 713px) 100vw, 713px\" \/><\/figure><\/div>\n\n\n<p>You should get a <strong>Deploy complete!<\/strong> message and an URL to the Project Console and the Hosting URL.<\/p>\n\n\n\n<p><strong>17)<\/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 Account\" 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\">2) Creating the Firebase Web App<\/h2>\n\n\n\n<p>Now that you&#8217;ve created a Firebase project app successfully on VS Code, follow the next steps to customize the app to display the picture saved on Firebase Storage.<\/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 last picture saved on the Firebase Storage and the time it was taken (<a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/\">created in this previous project<\/a>).<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;\n    &lt;title&gt;ESP Firebase App&lt;\/title&gt;\n\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;\n    &lt;link rel=&quot;stylesheet&quot; type=&quot;text\/css&quot; href=&quot;style.css&quot;&gt;\n\n    &lt;script type=&quot;module&quot; src=&quot;app.js&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=&quot;topnav&quot;&gt;\n        &lt;h1&gt;ESP32-CAM Web App &lt;i class=&quot;fas fa-camera&quot;&gt;&lt;\/i&gt;&lt;\/h1&gt;\n    &lt;\/div&gt;\n    &lt;p&gt;&lt;img id=&quot;img&quot; width=&quot;500px&quot;&gt;&lt;\/p&gt; \n    &lt;p&gt;Last picture taken: &lt;span id=&quot;date-time&quot;&gt;&lt;\/span&gt;&lt;\/p&gt;\n    &lt;button type=&quot;button&quot; id=&quot;refreshBtn&quot;&gt;Refresh&lt;\/button&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP32-CAM-Save-Picture-Firebase-Storage\/index.html\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>You need to modify the code with your own <span class=\"rnthl rntliteral\">firebaseConfig<\/span> object\u2014the one you&#8217;ve got <a href=\"#firebaseconfig-object\">in this step<\/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 <a href=\"#style-css\">skip to the next section<\/a>.<\/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 web page&#8217;s title 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>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>Load the app.js JavaScript file<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;script type=\"module\" src=\"app.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>This line tells the browser to load and execute the JavaScript file<strong> <span class=\"rnthl rntliteral\">app.js<\/span><\/strong> located in the same directory as the<strong> <span class=\"rnthl rntliteral\">index.html<\/span><\/strong> file\u2014we&#8217;ll create that file next.<\/p>\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> and <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;\/body&gt;<\/span><\/span> tags.<\/span><\/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;ESP32-CAM Web App &lt;i class=\"fas fa-camera\"&gt;&lt;\/i&gt;&lt;\/h1&gt;\n&lt;\/div&gt;<\/code><\/pre>\n\n\n\n<p>The following line creates a paragraph with an image tag where we&#8217;ll display the picture later on. The image tag has a specific id (&#8220;<span class=\"rnthl rntliteral\">img<\/span>&#8220;) so that we can refer to that element in the JavaScript file by its id.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;p&gt;&lt;img id=\"img\" width=\"500px\"&gt;&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<p>Next, we create a paragraph to display the date and time that the picture was taken. There is a <span class=\"rnthl rntliteral\"><span style=\"color: #333399;\">&lt;span&gt;<\/span><\/span> tag with the <span class=\"rnthl rntliteral\">date-time<\/span> id where we&#8217;ll display that information later on.<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;p&gt;Last picture taken: &lt;span id=\"date-time\"&gt;&lt;\/span&gt;&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<p> Finally, there&#8217;s a button to refresh the web page (to display a new picture, if that&#8217;s the case).<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;button onclick=\"window.location.reload();\"&gt;Refresh&lt;\/button&gt;<\/code><\/pre>\n\n\n\n<p>Save the HTML file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"style-css\">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: Arial, Helvetica, sans-serif; \r\n    display: inline-block; \r\n    text-align: center;\r\n  }\r\n  h1 {\r\n    font-size: 1.8rem; \r\n    color: white;\r\n  }\r\n  p { \r\n    font-size: 1.2rem;\r\n  }\r\n  .topnav { \r\n    overflow: hidden; \r\n    background-color: #0A1128;\r\n  }\r\n  body {  \r\n    margin: 0;\r\n  }\r\n  button{\r\n    background-color: #034078;\r\n    border: none;\r\n    padding: 14px 20px;\r\n    text-align: center;\r\n    font-size: 20px;\r\n    border-radius: 4px;\r\n    transition-duration: 0.4s;\r\n    width: 150px;\r\n    color: white;\r\n    cursor: pointer;\r\n  }<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Firebase-ESP\/raw\/main\/ESP32-CAM-Save-Picture-Firebase-Storage\/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 File<\/h3>\n\n\n\n<p>Create a new file inside the <span class=\"rnthl rntliteral\">public<\/span> folder called <span class=\"rnthl rntliteral\">app.js<\/span>.<\/p>\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=\"466\" height=\"267\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Web-App-Project-Files.png?resize=466%2C267&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project VS Code Folder File Structure\" class=\"wp-image-107985\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Web-App-Project-Files.png?w=466&amp;quality=100&amp;strip=all&amp;ssl=1 466w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/Firebase-Web-App-Project-Files.png?resize=300%2C172&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 466px) 100vw, 466px\" \/><\/figure><\/div>\n\n\n<h4 class=\"wp-block-heading\">app.js<\/h4>\n\n\n\n<p>Copy the following to the <span class=\"rnthl rntliteral\">app.js<\/span> file you created previously. <\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-javascript\">import { initializeApp } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-app.js';\r\nimport { getAuth, signInWithEmailAndPassword } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-auth.js';\r\nimport { getStorage, ref, getDownloadURL, getMetadata } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-storage.js';\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\nconst email = 'AUTHORIZED_USER_EMAIL'; \/\/ Replace with your user email\r\nconst password = 'PASSWORD'; \/\/ Replace with your user password\r\n\r\n\/\/ Initialize Firebase\r\nconst app = initializeApp(firebaseConfig);\r\nconst auth = getAuth(app);\r\nconst storage = getStorage(app);\r\n\r\n\/\/ Format date and time\r\nconst formatDateTime = (date) =&gt; {\r\n  const pad = (num) =&gt; String(num).padStart(2, '0');\r\n  return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())} at ${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\r\n};\r\n\r\n\/\/ Authenticate user\r\nconst authenticate = async () =&gt; {\r\n  try {\r\n    const userCredential = await signInWithEmailAndPassword(auth, email, password);\r\n    return userCredential.user;\r\n  } catch (error) {\r\n    document.getElementById('date-time').textContent = `Authentication error: ${error.message}`;\r\n    throw error;\r\n  }\r\n};\r\n\r\n\/\/ Load image and metadata\r\nconst loadImageData = async (user) =&gt; {\r\n  try {\r\n    const storageRef = ref(storage, 'data\/photo.jp');\r\n    const url = await getDownloadURL(storageRef);\r\n    document.querySelector('#img').src = url;\r\n\r\n    const metadata = await getMetadata(storageRef);\r\n    document.getElementById('date-time').textContent = formatDateTime(new Date(metadata.timeCreated));\r\n  } catch (error) {\r\n    document.getElementById('date-time').textContent = `Error: ${error.message}`;\r\n  }\r\n};\r\n\r\n\/\/ Initialize on page load\r\ndocument.addEventListener('DOMContentLoaded', async () =&gt; {\r\n  const user = await authenticate();\r\n  await loadImageData(user);\r\n\r\n  document.querySelector('#refreshBtn').addEventListener('click', async () =&gt; {\r\n    const user = await authenticate();\r\n    await loadImageData(user);\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\/ESP32-CAM-Save-Picture-Firebase-Storage\/app.js\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This file gets the picture saved on the Firebase Storage and the time it was taken, and displays that on the HTML page.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Firebase Modules<\/h4>\n\n\n\n<p>First, we load the necessary Firebase modules we&#8217;ll use.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>import { initializeApp } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-app.js';\nimport { getAuth, signInWithEmailAndPassword } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-auth.js';\nimport { getStorage, ref, getDownloadURL, getMetadata } from 'https:\/\/www.gstatic.com\/firebasejs\/10.14.1\/firebase-storage.js';<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Firebase Configuration Object<\/h4>\n\n\n\n<p>Then, add your Firebase configuration object for this project. The one you&#8217;ve got in <a href=\"#add-app-to-project\" title=\"\">previous steps in this tutorial<\/a>.<\/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\">User Email and Password<\/h4>\n\n\n\n<p>Insert the authorized user email and password. You should have set this up in <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/\" title=\"\">part 1 of this tutorial<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const email = 'AUTHORIZED_USER_EMAIL'; \/\/ Replace with your user email\nconst password = 'PASSWORD'; \/\/ Replace with your user password<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize the Firebase App<\/h4>\n\n\n\n<p>The following lines initialize the Firebase App.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Initialize Firebase\nconst app = initializeApp(firebaseConfig);\nconst auth = getAuth(app);\nconst storage = getStorage(app);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Format Data and Time<\/h4>\n\n\n\n<p>The following lines format data and time to be displayed on the web page in a specified format. For example: <span class=\"rnthl rntliteral\">11:05:11 at 2025-07-02<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Format date and time\nconst formatDateTime = (date) =&gt; {\n  const pad = (num) =&gt; String(num).padStart(2, '0');\n  return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())} at ${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Authentication<\/h4>\n\n\n\n<p>The following function will authenticate with the user and password we defined previously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Authenticate user\nconst authenticate = async () =&gt; {\n  try {\n    const userCredential = await signInWithEmailAndPassword(auth, email, password);\n    return userCredential.user;\n  } catch (error) {\n    document.getElementById('date-time').textContent = `Authentication error: ${error.message}`;\n    throw error;\n  }\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Load the Image and Metadata<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">loadImageData<\/span> function will get the image from Firebase storage and place it in the right place in the web page.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const loadImageData = async (user) =&gt; {\n  try {\n    const storageRef = ref(storage, 'data\/photo.jp');\n    const url = await getDownloadURL(storageRef);\n    document.querySelector('#img').src = url;<\/code><\/pre>\n\n\n\n<p>This is the specific line that gets a reference to the image:<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const storageRef = ref(storage, 'data\/photo.jp');<\/code><\/pre>\n\n\n\n<p class=\"rntbox rntcred\"><strong>Note<\/strong>: in my case, at the moment, there&#8217;s some sort of bug that truncates the name of the picture to <span class=\"rnthl rntliteral\">data\/photo.jp<\/span> instead of <span class=\"rnthl rntliteral\">data\/photo.jpg<\/span>. Adjust the name of the picture, if that&#8217;s not the case for you.<\/p>\n\n\n\n<p>We can get the time the image was taken from its metadata. The following lines get the date and time the picture was taken and place them in the right place in the web page.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const metadata = await getMetadata(storageRef);\ndocument.getElementById('date-time').textContent = formatDateTime(new Date(metadata.timeCreated));\n} catch (error) {\n  document.getElementById('date-time').textContent = `Error: ${error.message}`;\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize App on Page Load<\/h4>\n\n\n\n<p>The following lines will run every time you open or refresh the webpage.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>\/\/ Initialize on page load\ndocument.addEventListener('DOMContentLoaded', async () =&gt; {\n  const user = await authenticate();\n  await loadImageData(user);\n\n  document.querySelector('#refreshBtn').addEventListener('click', async () =&gt; {\n    const user = await authenticate();\n    await loadImageData(user);\n  });\n});<\/code><\/pre>\n\n\n\n<p>When that happens, we authenticate with the user and password.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const user = await authenticate();<\/code><\/pre>\n\n\n\n<p>Then, we load the image.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>await loadImageData(user);<\/code><\/pre>\n\n\n\n<p>We also add an event listener to the Refresh Button. When we click that button, it will authenticate with the user and password and also load the image.<\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>document.querySelector('#refreshBtn').addEventListener('click', async () =&gt; {\n  const user = await authenticate();\n  await loadImageData(user);\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Storage Rules<\/h3>\n\n\n\n<p>At the left sidebar of your Firebase Project, you should have a file called <strong><span class=\"rnthl rntliteral\">storage.rules<\/span><\/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=\"733\" height=\"377\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/Firebase-Storage-Rules-File.png?resize=733%2C377&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Storage Rules File on VS Code\" class=\"wp-image-173164\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/Firebase-Storage-Rules-File.png?w=733&amp;quality=100&amp;strip=all&amp;ssl=1 733w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/Firebase-Storage-Rules-File.png?resize=300%2C154&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 733px) 100vw, 733px\" \/><\/figure><\/div>\n\n\n<p>Open that file and copy the following rules. These rules allow any authenticated user to read and write to Firebase Storage. Save the file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rules_version = '2';\n\n\/\/ Craft rules based on data in your Firestore database\nservice firebase.storage {\n  match \/b\/{bucket}\/o {\n    match \/{allPaths=**} {\n      allow read, write: if request.auth != null;\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Deploy your App<\/h3>\n\n\n\n<p>After saving the HTML and JavaScript files, deploy your app on VS Code by running the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>firebase<\/strong> deploy<\/code><\/pre>\n\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>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>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 on the Hosting URL provided. In my case, it is <span class=\"rnthl rntliteral\">https:\/\/esp-firebase-demo.web.app<\/span>.<\/p>\n\n\n\n<p>The web app is responsive, and you can access it using your smartphone, computer, or tablet.<\/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=\"350\" height=\"715\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Web-App-Smartphone-Picture.png?resize=350%2C715&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Firebase Web App Display Picture Smartphone\" class=\"wp-image-108014\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Web-App-Smartphone-Picture.png?w=350&amp;quality=100&amp;strip=all&amp;ssl=1 350w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Web-App-Smartphone-Picture.png?resize=147%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 147w\" sizes=\"(max-width: 350px) 100vw, 350px\" \/><\/figure><\/div>\n\n\n<p>Reset your ESP32-CAM board, and it should take a new picture when it first starts. Then, click on the web app Refresh button so that it retrieves the latest picture taken.<\/p>\n\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 that interacts with Firebase Storage to display the last image taken with the ESP32-CAM.<\/p>\n\n\n\n<p>You can apply what you learned here to display any other type of file (not just jpeg), and you can change the files in the <span class=\"rnthl rntliteral\">public<\/span> folder to add different functionalities and features to your project. For example, add an authentication form, display multiple pictures, etc.<\/p>\n\n\n\n<p>If you want to learn more about Firebase, we recommend taking a look at our new eBook:<\/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 the last picture taken with an ESP32-CAM saved in the Firebase Storage. The Web App also shows the date &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32-CAM: Display Pictures in Firebase Web App\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-display-pictures-firebase-web-app\/#more-107976\" aria-label=\"Read more about ESP32-CAM: Display Pictures in Firebase Web App\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":108007,"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,319,264],"tags":[],"class_list":["post-107976","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32-cam","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/11\/ESP32-CAM-Firebase-Web-App.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107976","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=107976"}],"version-history":[{"count":26,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107976\/revisions"}],"predecessor-version":[{"id":219728,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107976\/revisions\/219728"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/108007"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=107976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=107976"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=107976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}