{"id":107690,"date":"2025-07-01T09:50:02","date_gmt":"2025-07-01T09:50:02","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=107690"},"modified":"2026-05-08T20:36:04","modified_gmt":"2026-05-08T20:36:04","slug":"esp32-cam-save-picture-firebase-storage","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/","title":{"rendered":"ESP32-CAM Save Picture in Firebase Storage"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll learn how to take and upload a picture to Firebase Storage using the ESP32-CAM. You&#8217;ll create a Firebase project with Storage that allows you to store your files. Then, you can access your Firebase console to visualize the pictures or create a web app to display them (we&#8217;ll do this in a future tutorial). The ESP32-CAM will be programmed using Arduino IDE.<\/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\/2023\/09\/ESP32-CAM-Upload-Pictures-to-Firebase-Sotrage.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Save Picture in Firebase Storage Tutorial Guide\" class=\"wp-image-172799\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-CAM-Upload-Pictures-to-Firebase-Sotrage.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-CAM-Upload-Pictures-to-Firebase-Sotrage.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-CAM-Upload-Pictures-to-Firebase-Sotrage.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-CAM-Upload-Pictures-to-Firebase-Sotrage.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 8, 2026.<\/em><\/p>\n\n\n\n<p><strong>Note:&nbsp;<\/strong>this project is compatible with any <a href=\"https:\/\/makeradvisor.com\/esp32-camera-cam-boards-review-comparison\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Camera Board with the OV2640 camera<\/a>. You just need to make sure you use the right&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-ai-thinker-pinout\/\">pinout for the board<\/a>&nbsp;you&#8217;re using.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is Firebase?<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"196\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Firebase-Logo.png?resize=750%2C196&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Logo\" class=\"wp-image-169096\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Firebase-Logo.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Firebase-Logo.png?resize=300%2C78&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Firebase is Google&#8217;s mobile application development platform that helps you build, improve, and grow your app. It has many services used to manage data from any Android, IOS, or web application like <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-authentication\/\">authentication<\/a>,&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-realtime-database\/\">realtime database<\/a>,&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-web-app\/\">hosting<\/a>, storage, etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>This simple tutorial exemplifies how to take and send photos taken with the ESP32-CAM to Firebase Storage. The ESP32-CAM takes a picture and sends it to Firebase every time it resets (press the RST button). The idea is that you add some sort of trigger that might be useful for your projects, like a <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-pir-motion-detector-photo-capture\/\">PIR motion sensor<\/a> or a pushbutton, for example.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"755\" height=\"228\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Storage-Project-Overview-update.png?resize=755%2C228&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-136613\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Storage-Project-Overview-update.png?w=755&amp;quality=100&amp;strip=all&amp;ssl=1 755w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/01\/ESP32-CAM-Firebase-Storage-Project-Overview-update.png?resize=300%2C91&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>When the ESP32 first runs, it takes a new picture and saves it in the filesystem (LittleFS);<\/li>\n\n\n\n<li>The ESP32-CAM connects to Firebase as a user with email and password;<\/li>\n\n\n\n<li>The ESP32-CAM sends the picture to Firebase Storage;<\/li>\n\n\n\n<li>After that, you can go to your Firebase console to view the pictures;<\/li>\n\n\n\n<li>Later, you can build a web app that you can access from anywhere to display the ESP32-CAM pictures (we&#8217;ll create this in a future tutorial).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Contents<\/h2>\n\n\n\n<p>Here&#8217;s a summary of the steps you need to follow to create this project.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"#create-firebase-project\">Create a Firebase Project<\/a><\/li>\n\n\n\n<li><a href=\"#set-authentication-methods\">Set Authentication Methods<\/a><\/li>\n\n\n\n<li><a href=\"#create-storage-bucket\">Create Storage Bucket<\/a><\/li>\n\n\n\n<li><a href=\"#get-API-Key\">Get Project API Key<\/a><\/li>\n\n\n\n<li><span style=\"font-size: inherit;\"><a href=\"#esp32-cam-send-pictures-firebase\">ESP32-CAM Send Pictures to Firebase Storage<\/a><\/span><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-firebase-project\">1) Create a Firebase Project<\/h2>\n\n\n\n<p>Follow the next instructions to create a new project on Firebase.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <a href=\"https:\/\/firebase.google.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Firebase <\/a>and sign in using a Google Account.<\/li>\n\n\n\n<li>Go to the <a href=\"https:\/\/console.firebase.google.com\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Firebase Console<\/a> and create a new project.<\/li>\n\n\n\n<li>Give a name to your project, for example: <em>ESP-Project,<\/em> and click <strong>Continue<\/strong>.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105729\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/1-create-firebase-project.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Set Up Firebase Project for ESP32 and ESP8266 Step 1\"><\/figure><\/li>\n\n\n\n<li>Next, enable or disable AI assistance for your project. This is optional.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105729\" style=\"width: 739px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/2-create-firebase-project-ai-assistance.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Set Up Firebase Project for ESP32 and ESP8266 - Enable AI assistant\"><\/figure><\/li>\n\n\n\n<li>Disable the option <em>Enable Google Analytics<\/em> for this project, as it is not needed. Then, click <strong>Create project<\/strong>.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105730\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/3-create-firebase-project.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Disable Google Analytics for firebase project\"><\/figure><\/li>\n\n\n\n<li>It will take a few seconds to set up your project. Click <strong>Continue <\/strong>when it&#8217;s ready.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105731\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/5-Firebase-project-ready.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project for ESP32 Ready\"><\/figure><br><\/li>\n\n\n\n<li>You&#8217;ll be redirected to your Project console page.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105732\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/6-Firebase-console-ESP-project.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase console project\"><\/figure><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"set-authentication-methods\">2) Set Authentication Methods<\/h2>\n\n\n\n<p>You need to set authentication methods for your app. <\/p>\n\n\n\n<p>&#8220;Most apps need to know the identity of a user. In other words, it takes care of logging in and identifying the users (in this case, the ESP32). Knowing a user&#8217;s identity allows an app to securely save user data in the cloud &#8230;&#8221; To learn more about the authentication methods, you can <a href=\"https:\/\/firebase.google.com\/docs\/auth\" target=\"_blank\" rel=\"noreferrer noopener\">read the documentation<\/a>.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the left sidebar, click on <strong>Build <\/strong>&gt; <strong>Authentication <\/strong>and then on <strong>Get started<\/strong>. <br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105735\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/7-set-authentication.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase project set authentication\"><\/figure><\/li>\n\n\n\n<li>There are several authentication methods like email and password, Google Account, Facebook account, and others.<figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105740\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/8-Firebase-authentication-methods.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"SFirebase authentication methods\"><\/figure><\/li>\n\n\n\n<li>Select <strong>Email\/Password<\/strong> and <strong>enable <\/strong>that authentication method. Then, click <strong>Save<\/strong>.<figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105741\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/9-enable-email-password-firebase.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Enable Email Password Sign in Firebase\"><\/figure><\/li>\n\n\n\n<li>Then, at the top, click on the <strong>Users <\/strong>tab. Then, click on <strong>Add user<\/strong>. <figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105741\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/10-add-user-email-password-firebase.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Create a new user\"><\/figure><\/li>\n\n\n\n<li>Create a new user with an email and password. The email can be your personal email. Create a password for that user (you need to remember the password later). Finally, click on <strong>Add user<\/strong>.<figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105741\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/11-add-user-email-pass.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase add user email and password\"><\/figure><\/li>\n\n\n\n<li>The User will show up on the list of users. You can see information about the user, like when it was created, the last time it signed in, and its user UID.<figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105741\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/04\/12-user-created-firebase.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase User Created\"><\/figure><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-storage-bucket\">3) Creating a Storage Bucket<\/h2>\n\n\n\n<p><strong>1)<\/strong> On the left sidebar, click on <strong>Build <\/strong>&gt; <strong>Storage <\/strong>and then on <strong>Get started<\/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=\"746\" height=\"597\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Project-Build-Storage.png?resize=746%2C597&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Console Create a Storage Bucket\" class=\"wp-image-171488\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Project-Build-Storage.png?w=746&amp;quality=100&amp;strip=all&amp;ssl=1 746w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Project-Build-Storage.png?resize=300%2C240&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 746px) 100vw, 746px\" \/><\/figure><\/div>\n\n\n<p>To use Firebase Storage, you need to upgrade your project to a paid plan. But don\u2019t worry \u2014 they offer 5GB of free storage, which is more than enough to run this and many other projects for a long time without paying anything. Additionally, you can set a maximum spending limit.<\/p>\n\n\n\n<p><strong>2)<\/strong> Create a billing account to link to your project.<\/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=\"528\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Create-Billing-Acoount.png?resize=750%2C528&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Storage - Create a billing acount\" class=\"wp-image-171489\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Create-Billing-Acoount.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Create-Billing-Acoount.png?resize=300%2C211&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Set the <em>Pay as you go<\/em> Blaze Plan.<\/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=\"740\" height=\"755\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Storage-Pay-as-you-go-blaze-plan.jpg?resize=740%2C755&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Pay as You Go Blaze Plan\" class=\"wp-image-171490\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Storage-Pay-as-you-go-blaze-plan.jpg?w=740&amp;quality=100&amp;strip=all&amp;ssl=1 740w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Storage-Pay-as-you-go-blaze-plan.jpg?resize=294%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 294w\" sizes=\"(max-width: 740px) 100vw, 740px\" \/><\/figure><\/div>\n\n\n<p><strong>3)<\/strong> After creating and setting up your billing account and linking it to your project, return to your project console to create a <strong>Storage Bucket<\/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=\"810\" height=\"376\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Get-Started.png?resize=810%2C376&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Storage Get Started\" class=\"wp-image-171491\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Get-Started.png?w=810&amp;quality=100&amp;strip=all&amp;ssl=1 810w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Get-Started.png?resize=300%2C139&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Get-Started.png?resize=768%2C357&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 810px) 100vw, 810px\" \/><\/figure><\/div>\n\n\n<p><strong>4)<\/strong> Select the database location.<\/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=\"727\" height=\"551\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Set-Up-Default-Bucket.png?resize=727%2C551&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Set Up Default Storage Bucket\" class=\"wp-image-171492\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Set-Up-Default-Bucket.png?w=727&amp;quality=100&amp;strip=all&amp;ssl=1 727w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firabase-Set-Up-Default-Bucket.png?resize=300%2C227&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 727px) 100vw, 727px\" \/><\/figure><\/div>\n\n\n<p><strong>5)<\/strong> Select <em>Start in <strong>test mode<\/strong><\/em>\u2014click <strong>Next<\/strong>. We&#8217;ll change the storage rules later on.<\/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=\"744\" height=\"590\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/5-set-up-default-bucket.png?resize=744%2C590&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firabase Storage Bucket Start in Test Mode\" class=\"wp-image-171494\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/5-set-up-default-bucket.png?w=744&amp;quality=100&amp;strip=all&amp;ssl=1 744w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/5-set-up-default-bucket.png?resize=300%2C238&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 744px) 100vw, 744px\" \/><\/figure><\/div>\n\n\n<p><strong>6)<\/strong> The storage bucket is now set up. Copy the storage bucket ID\u2014 you&#8217;ll need it later. <u>Don&#8217;t<\/u> copy the <span class=\"rnthl rntliteral\">gs:\/\/<\/span> section.<\/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=\"738\" height=\"444\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Bucket-Storage-Created-Bucket-ID.png?resize=738%2C444&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Storage Bucket Created\" class=\"wp-image-171500\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Bucket-Storage-Created-Bucket-ID.png?w=738&amp;quality=100&amp;strip=all&amp;ssl=1 738w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Bucket-Storage-Created-Bucket-ID.png?resize=300%2C180&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 738px) 100vw, 738px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Storage Rules<\/h3>\n\n\n\n<p>We&#8217;ll change the storage rules so that only authenticated users can upload files to the storage bucket. Select the <strong>Rules<\/strong> tab.<\/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=\"502\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Bucket-Change-Rules.png?resize=750%2C502&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Storage Bucket - Change Rules\" class=\"wp-image-171498\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Bucket-Change-Rules.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Bucket-Change-Rules.png?resize=300%2C201&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Change your database rules. Use the following rules:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rules_version = '2';\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<p>When you&#8217;re done, click <strong>Publish<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"get-API-Key\">4) Creating a Web App for Your Project (and API key)<\/h2>\n\n\n\n<p>To interface with your Firebase project using the ESP32-CAM, you need to get your project API key. To get an API key for your project, you need to create a web app first. Follow the next steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the left sidebar, click on <strong>Settings<\/strong>.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105748\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/05\/2-firebase-project-settings.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Realtime Database Project Settings\"><\/figure><\/li>\n\n\n\n<li>Scroll down on that page to the <strong>Your apps<\/strong> section. Then, click on the web icon <strong>&lt;\/&gt;<\/strong> to create and add a web app to your Firebase project.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105749\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/05\/3-Firebase-add-app-to-project.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project API Key\"><\/figure><\/li>\n\n\n\n<li>Give your app a name. Then, check the box next to\u00a0<strong>\u221a Also set up Firebase Hosting for this App<\/strong>. Click <strong>Register app<\/strong>.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105749\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/05\/4-add-firebase-to-app.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project API Key\"><\/figure><\/li>\n\n\n\n<li>Then, in the firebaseConfig object, you can find your API key. Save it because you&#8217;ll need it later.<br><figure><img data-recalc-dims=\"1\" decoding=\"async\" class=\"wp-image-105749\" style=\"width: 750px;\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2026\/05\/5-firebaseconfig-object-api-key-f.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Firebase Project API Key\"><\/figure>After this, you can also access the <span class=\"rnthl rntliteral\">firebaseConfig<\/span> object if you go to your Project settings in your Firebase console and scroll down to the <strong>Your apps<\/strong> section.<\/li>\n\n\n\n<li>Click\u00a0Next\u00a0on the preceding steps, and finally on <strong>Continue to console<\/strong>.<\/li>\n<\/ol>\n\n\n\n<p>Now, you have everything ready to interface the ESP32 with the database.<\/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\" id=\"esp32-cam-send-pictures-firebase\">5) ESP32-CAM &#8211; Send Pictures to Firebase Storage<\/h2>\n\n\n\n<p>Before proceeding with the tutorial, make sure you check the following prerequisites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing the ESP32 Boards in Arduino IDE<\/h3>\n\n\n\n<p>We&#8217;ll program the ESP32-CAM board using Arduino IDE. So you need the Arduino IDE installed as well as the ESP32 core. Follow the next tutorial to install it, if you haven&#8217;t already.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Installing ESP Firebase Client Library<\/h3>\n\n\n\n<p>For this tutorial, you need to install the <a href=\"https:\/\/github.com\/mobizt\/FirebaseClient\" title=\"\">FirebaseClient Library<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Installation &#8211; Arduino IDE<\/h4>\n\n\n\n<p>Follow this section if you&#8217;re using Arduino IDE. <\/p>\n\n\n\n<p>Go to <strong>Sketch <\/strong>&gt; <strong>Include Library<\/strong> &gt; <strong>Manage Libraries<\/strong>, search for the library name, and install it.<\/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=\"790\" height=\"586\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/install-Firebase-client-arduino-ide.png?resize=790%2C586&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install Firebase Client Library Arduino IDE\" class=\"wp-image-169118\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/install-Firebase-client-arduino-ide.png?w=790&amp;quality=100&amp;strip=all&amp;ssl=1 790w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/install-Firebase-client-arduino-ide.png?resize=300%2C223&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/install-Firebase-client-arduino-ide.png?resize=768%2C570&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 790px) 100vw, 790px\" \/><\/figure><\/div>\n\n\n<p>Now, you&#8217;re all set to start programming the ESP32 and ESP8266 boards to interact with the database.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Installing Libraries &#8211; VS Code<\/h4>\n\n\n\n<p>Follow the next instructions if you&#8217;re using VS Code with the PlatformIO or pioarduino extension.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Install the FirebaseClient Library<\/strong><\/h5>\n\n\n\n<p>Click on the <strong>PIO Home<\/strong> icon and select the <strong>Libraries tab<\/strong>. Search for &#8220;<strong>FirebaseClient<\/strong>&#8220;. Select the <strong>FirebaseClient Library<\/strong> by Mobitz.<\/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=\"646\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Install-FirebsaeClient-Library-VS-Code.jpg?resize=750%2C646&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install FirebaseClient Library VS Code\" class=\"wp-image-169174\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Install-FirebsaeClient-Library-VS-Code.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Install-FirebsaeClient-Library-VS-Code.jpg?resize=300%2C258&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Then, click <strong>Add to Project<\/strong> and select the project you&#8217;re working on.<\/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=\"341\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Add-FirebaseClient-library-to-project-VS-Code.jpg?resize=750%2C341&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Add FirebaseClient Library ro project in VS Code\" class=\"wp-image-169175\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Add-FirebaseClient-library-to-project-VS-Code.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/09\/Add-FirebaseClient-library-to-project-VS-Code.jpg?resize=300%2C136&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Then, click <strong>Add to Project<\/strong> and select the project you&#8217;re working on.<\/p>\n\n\n\n<p>Also, change the monitor speed to 115200 by adding the following line to the <span class=\"rnthl rntliteral\">platformio.ini<\/span> file of your project:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>monitor_speed = 115200<\/code><\/pre>\n\n\n\n<p>Now, you&#8217;re all set to start programming the ESP32-CAM board to send pictures to Firebase Storage.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ESP32-CAM Send Pictures to Firebase &#8211; Code<\/h3>\n\n\n\n<p>Copy the following code to the Arduino IDE, or to the <span class=\"rnthl rntliteral\">main.cpp<\/span> file if you&#8217;re using VS Code. It takes a picture and sends it to Firebase when it first boots.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\r\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n  Complete instructions at: https:\/\/RandomNerdTutorials.com\/esp32-cam-save-picture-firebase-storage\/\r\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n  Based on the example provided by the ESP Firebase Client Library\r\n*********\/\r\n#define ENABLE_USER_AUTH\r\n#define ENABLE_STORAGE\r\n#define ENABLE_FS\r\n\r\n#include &lt;Arduino.h&gt;\r\n#include &lt;FirebaseClient.h&gt;\r\n#include &lt;FS.h&gt;\r\n#include &lt;LittleFS.h&gt;\r\n#include &lt;WiFi.h&gt;\r\n#include &lt;WiFiClientSecure.h&gt;\r\n#include &quot;esp_camera.h&quot;\r\n\r\n#define WIFI_SSID &quot;REPLACE_WITH_YOUR_SSID&quot;\r\n#define WIFI_PASSWORD &quot;REPLACE_WITH_YOUR_PASSWORD&quot;\r\n\r\n#define API_KEY &quot;REPLACE_WITH_YOUR_FIREBASE_PROJECT_API_KEY&quot;\r\n#define USER_EMAIL &quot;REPLACE_WITH_FIREBASE_PROJECT_EMAIL_USER&quot;\r\n#define USER_PASSWORD &quot;REPLACE_WITH_FIREBASE_PROJECT_USER_PASS&quot;\r\n\r\n\/\/ Define the Firebase storage bucket ID e.g bucket-name.appspot.com *\/\r\n#define STORAGE_BUCKET_ID &quot;REPLACE_WITH_STORAGE_BUCKET_ID&quot;\r\n\r\n\/\/ Photo path in filesystem and photo path in Firebase bucket\r\n#define FILE_PHOTO_PATH &quot;\/photo.jpg&quot;\r\n#define BUCKET_PHOTO_PATH &quot;\/data\/photo.jpg&quot;\r\n\r\n\/\/ User functions\r\nvoid processData(AsyncResult &amp;aResult);\r\nvoid file_operation_callback(File &amp;file, const char *filename, file_operating_mode mode);\r\n\r\nFileConfig media_file(FILE_PHOTO_PATH, file_operation_callback); \/\/ Can be set later with media_file.setFile(&quot;\/image.png&quot;, file_operation_callback);\r\n\r\nFile myFile;\r\n\r\n\/\/ Authentication\r\nUserAuth user_auth(API_KEY, USER_EMAIL, USER_PASSWORD, 3000 \/* expire period in seconds (&lt;3600) *\/);\r\n\r\n\/\/ Firebase components\r\nFirebaseApp app;\r\nWiFiClientSecure ssl_client;\r\nusing AsyncClient = AsyncClientClass;\r\nAsyncClient aClient(ssl_client);\r\nStorage storage;\r\n\r\nbool taskComplete = false;\r\n\r\nAsyncResult storageResult;\r\n\r\n\/\/ OV2640 camera module pins (CAMERA_MODEL_AI_THINKER)\r\n#define PWDN_GPIO_NUM     32\r\n#define RESET_GPIO_NUM    -1\r\n#define XCLK_GPIO_NUM      0\r\n#define SIOD_GPIO_NUM     26\r\n#define SIOC_GPIO_NUM     27\r\n#define Y9_GPIO_NUM       35\r\n#define Y8_GPIO_NUM       34\r\n#define Y7_GPIO_NUM       39\r\n#define Y6_GPIO_NUM       36\r\n#define Y5_GPIO_NUM       21\r\n#define Y4_GPIO_NUM       19\r\n#define Y3_GPIO_NUM       18\r\n#define Y2_GPIO_NUM        5\r\n#define VSYNC_GPIO_NUM    25\r\n#define HREF_GPIO_NUM     23\r\n#define PCLK_GPIO_NUM     22\r\n\r\nboolean takeNewPhoto = true;\r\n\r\n\/\/ Capture Photo and Save it to LittleFS\r\nvoid capturePhotoSaveLittleFS( void ) {\r\n  \/\/ Dispose first pictures because of bad quality\r\n  camera_fb_t* fb = NULL;\r\n  \/\/ Skip first 3 frames (increase\/decrease number as needed).\r\n  for (int i = 0; i &lt; 10; i++) {\r\n    fb = esp_camera_fb_get();\r\n    esp_camera_fb_return(fb);\r\n    fb = NULL;\r\n  }\r\n    \r\n  \/\/ Take a new photo\r\n  fb = NULL;  \r\n  fb = esp_camera_fb_get();  \r\n  if(!fb) {\r\n    Serial.println(&quot;Camera capture failed&quot;);\r\n    delay(1000);\r\n    ESP.restart();\r\n  }  \r\n\r\n  \/\/ Photo file name\r\n  Serial.printf(&quot;Picture file name: %s\\n&quot;, FILE_PHOTO_PATH);\r\n  File file = LittleFS.open(FILE_PHOTO_PATH, FILE_WRITE);\r\n\r\n  \/\/ Insert the data in the photo file\r\n  if (!file) {\r\n    Serial.println(&quot;Failed to open file in writing mode&quot;);\r\n  }\r\n  else {\r\n    file.write(fb-&gt;buf, fb-&gt;len); \/\/ payload (image), payload length\r\n    Serial.print(&quot;The picture has been saved in &quot;);\r\n    Serial.print(FILE_PHOTO_PATH);\r\n    Serial.print(&quot; - Size: &quot;);\r\n    Serial.print(fb-&gt;len);\r\n    Serial.println(&quot; bytes&quot;);\r\n  }\r\n  \/\/ Close the file\r\n  file.close();\r\n  esp_camera_fb_return(fb);\r\n  delay(100);\r\n}\r\n\r\nvoid initLittleFS(){\r\n  if (!LittleFS.begin(true)) {\r\n    Serial.println(&quot;An Error has occurred while mounting LittleFS&quot;);\r\n    ESP.restart();\r\n  }\r\n  else {\r\n    delay(500);\r\n    Serial.println(&quot;LittleFS mounted successfully&quot;);\r\n  }\r\n}\r\n\r\nvoid initWiFi(){\r\n  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);\r\n  while (WiFi.status() != WL_CONNECTED) {\r\n    delay(1000);\r\n    Serial.println(&quot;Connecting to WiFi...&quot;);\r\n  }\r\n}\r\n\r\nvoid initCamera(){\r\n \/\/ OV2640 camera module\r\n  camera_config_t config;\r\n  config.ledc_channel = LEDC_CHANNEL_0;\r\n  config.ledc_timer = LEDC_TIMER_0;\r\n  config.pin_d0 = Y2_GPIO_NUM;\r\n  config.pin_d1 = Y3_GPIO_NUM;\r\n  config.pin_d2 = Y4_GPIO_NUM;\r\n  config.pin_d3 = Y5_GPIO_NUM;\r\n  config.pin_d4 = Y6_GPIO_NUM;\r\n  config.pin_d5 = Y7_GPIO_NUM;\r\n  config.pin_d6 = Y8_GPIO_NUM;\r\n  config.pin_d7 = Y9_GPIO_NUM;\r\n  config.pin_xclk = XCLK_GPIO_NUM;\r\n  config.pin_pclk = PCLK_GPIO_NUM;\r\n  config.pin_vsync = VSYNC_GPIO_NUM;\r\n  config.pin_href = HREF_GPIO_NUM;\r\n  config.pin_sccb_sda = SIOD_GPIO_NUM;\r\n  config.pin_sccb_scl = SIOC_GPIO_NUM;\r\n  config.pin_pwdn = PWDN_GPIO_NUM;\r\n  config.pin_reset = RESET_GPIO_NUM;\r\n  config.xclk_freq_hz = 20000000;\r\n  config.pixel_format = PIXFORMAT_JPEG;\r\n  config.grab_mode = CAMERA_GRAB_LATEST;\r\n\r\n  if (psramFound()) {\r\n    config.frame_size = FRAMESIZE_UXGA;\r\n    config.jpeg_quality = 10;\r\n    config.fb_count = 1;\r\n  } else {\r\n    config.frame_size = FRAMESIZE_SVGA;\r\n    config.jpeg_quality = 12;\r\n    config.fb_count = 1;\r\n  }\r\n  \/\/ Camera init\r\n  esp_err_t err = esp_camera_init(&amp;config);\r\n  if (err != ESP_OK) {\r\n    Serial.printf(&quot;Camera init failed with error 0x%x&quot;, err);\r\n    ESP.restart();\r\n  }\r\n  Serial.print(&quot;Camera init success&quot;);\r\n}\r\n\r\nvoid setup(){\r\n    Serial.begin(115200);\r\n    initWiFi();\r\n    initCamera();\r\n\r\n    Firebase.printf(&quot;Firebase Client v%s\\n&quot;, FIREBASE_CLIENT_VERSION);\r\n\r\n    initLittleFS();\r\n\r\n    \/\/ Configure SSL client\r\n    ssl_client.setInsecure();\r\n    ssl_client.setConnectionTimeout(1000);\r\n    ssl_client.setHandshakeTimeout(5);\r\n    Serial.println(&quot;Initializing app...&quot;);\r\n    initializeApp(aClient, app, getAuth(user_auth), processData, &quot;\ud83d\udd10 authTask&quot;);\r\n\r\n    app.getApp&lt;Storage&gt;(storage);\r\n\r\n    Serial.println(&quot;Listing files in LittleFS:&quot;);\r\n    File root = LittleFS.open(&quot;\/&quot;);\r\n    File file = root.openNextFile();\r\n    while (file) {\r\n        Serial.println(file.name());\r\n        file = root.openNextFile();\r\n    }\r\n\r\n}\r\n\r\nvoid loop(){\r\n    \/\/ To maintain the authentication process.\r\n    app.loop();\r\n\r\n    if (app.ready() &amp;&amp; !taskComplete &amp;&amp; takeNewPhoto){\r\n        taskComplete = true;\r\n        takeNewPhoto = false;\r\n\r\n        capturePhotoSaveLittleFS();\r\n        \r\n        \/\/ Async call with callback function.\r\n        storage.upload(aClient, FirebaseStorage::Parent(STORAGE_BUCKET_ID, BUCKET_PHOTO_PATH), getFile(media_file), &quot;image\/jpg&quot;, processData, &quot;\u2b06\ufe0f  uploadTask&quot;);\r\n    }\r\n}\r\n\r\nvoid processData(AsyncResult &amp;aResult)\r\n{\r\n    \/\/ Exits when no result available when calling from the loop.\r\n    if (!aResult.isResult())\r\n        return;\r\n\r\n    if (aResult.isEvent())\r\n    {\r\n        Firebase.printf(&quot;Event task: %s, msg: %s, code: %d\\n&quot;, aResult.uid().c_str(), aResult.appEvent().message().c_str(), aResult.appEvent().code());\r\n    }\r\n\r\n    if (aResult.isDebug())\r\n    {\r\n        Firebase.printf(&quot;Debug task: %s, msg: %s\\n&quot;, aResult.uid().c_str(), aResult.debug().c_str());\r\n    }\r\n\r\n    if (aResult.isError())\r\n    {\r\n        Firebase.printf(&quot;Error task: %s, msg: %s, code: %d\\n&quot;, aResult.uid().c_str(), aResult.error().message().c_str(), aResult.error().code());\r\n    }\r\n\r\n    if (aResult.downloadProgress())\r\n    {\r\n        Firebase.printf(&quot;Downloaded, task: %s, %d%s (%d of %d)\\n&quot;, aResult.uid().c_str(), aResult.downloadInfo().progress, &quot;%&quot;, aResult.downloadInfo().downloaded, aResult.downloadInfo().total);\r\n        if (aResult.downloadInfo().total == aResult.downloadInfo().downloaded)\r\n        {\r\n            Firebase.printf(&quot;Download task: %s, complete!\u2705\ufe0f\\n&quot;, aResult.uid().c_str());\r\n        }\r\n    }\r\n\r\n    if (aResult.uploadProgress())\r\n    {\r\n        Firebase.printf(&quot;Uploaded, task: %s, %d%s (%d of %d)\\n&quot;, aResult.uid().c_str(), aResult.uploadInfo().progress, &quot;%&quot;, aResult.uploadInfo().uploaded, aResult.uploadInfo().total);\r\n        if (aResult.uploadInfo().total == aResult.uploadInfo().uploaded)\r\n        {\r\n            Firebase.printf(&quot;Upload task: %s, complete!\u2705\ufe0f\\n&quot;, aResult.uid().c_str());\r\n            Serial.print(&quot;Download URL: &quot;);\r\n            Serial.println(aResult.uploadInfo().downloadUrl);\r\n        }\r\n    }\r\n}\r\n\r\nvoid file_operation_callback(File &amp;file, const char *filename, file_operating_mode mode){\r\n    \/\/ FILE_OPEN_MODE_READ, FILE_OPEN_MODE_WRITE and FILE_OPEN_MODE_APPEND are defined in this library\r\n    \/\/ MY_FS is defined in this example\r\n    switch (mode)    {\r\n    case file_mode_open_read:\r\n        myFile = LittleFS.open(filename, &quot;r&quot;);\r\n        if (!myFile || !myFile.available()) {\r\n            Serial.println(&quot;[ERROR] Failed to open file for reading&quot;);\r\n        }\r\n        break;\r\n    case file_mode_open_write:\r\n        myFile = LittleFS.open(filename, &quot;w&quot;);\r\n        break;\r\n    case file_mode_open_append:\r\n        myFile = LittleFS.open(filename, &quot;a&quot;);\r\n        break;\r\n    case file_mode_remove:\r\n        LittleFS.remove(filename);\r\n        break;\r\n    default:\r\n        break;\r\n    }\r\n    \/\/ Set the internal FS object with global File object.\r\n    file = myFile;\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\/ESP32-CAM-Save-Picture-Firebase-Storage.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>You need to insert your network credentials, Firebase user and password, storage bucket URL, and project API key for the project to work.<\/p>\n\n\n\n<p>This sketch was based on a <a href=\"https:\/\/github.com\/mobizt\/FirebaseClient\/blob\/main\/examples\/Storage\/Upload\/Upload.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">basic example&nbsp;provided by the library<\/a>. You can find more <a href=\"https:\/\/github.com\/mobizt\/FirebaseClient\/tree\/main\/examples\" target=\"_blank\" rel=\"noopener\" title=\"\">examples&nbsp;here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#demonstration\">demonstration section<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Libraries<\/h4>\n\n\n\n<p>First, include the required libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;Arduino.h&gt;\n#include &lt;FirebaseClient.h&gt;\n#include &lt;FS.h&gt;\n#include &lt;LittleFS.h&gt;\n#include &lt;WiFi.h&gt;\n#include &lt;WiFiClientSecure.h&gt;\n#include \"esp_camera.h\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Network Credentials<\/h4>\n\n\n\n<p>Insert your network credentials in the following variables so that the ESP can connect to the internet and communicate with Firebase.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/Replace with your network credentials\n#define WIFI_SSID \"REPLACE_WITH_YOUR_SSID\"\n#define WIFI_PASSWORD \"REPLACE_WITH_YOUR_PASSWORD\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Firebase Project API Key<\/h4>\n\n\n\n<p>Insert your Firebase project API key\u2014see this section: <a href=\"#get-API-Key\">4) Get Project API Key<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define API_KEY \"REPLACE_WITH_YOUR_FIREBASE_PROJECT_API_KEY\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">User Email and Password<\/h4>\n\n\n\n<p>Insert the authorized email and the corresponding password\u2014see this section: <a href=\"#set-authentication-methods\">2) Set Authentication Methods<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define USER_EMAIL \"REPLACE_WITH_FIREBASE_PROJECT_EMAIL_USER\"\n#define USER_PASSWORD \"REPLACE_WITH_FIREBASE_PROJECT_USER_PASS\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Firebase Storage Bucket ID<\/h4>\n\n\n\n<p>Insert the Firebase storage bucket ID, e.g <em><a href=\"gs:\/\/esp-project-598f5.firebasestorage.app\">bucket-name.appspot.com<\/a><\/em>. In my case, it is <em>esp-project-598f5.firebasestorage.app<\/em>. (remove any slashes &#8220;\/&#8221; at the end or at the beginning of the bucket ID, otherwise, it will not work).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define STORAGE_BUCKET_ID \"REPLACE_WITH_YOUR_STORAGE_BUCKET_ID\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Picture Path<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">FILE_PHOTO_PATH<\/span> variable defines the LittleFS path where the picture will be saved. It will be saved with the name <span class=\"rnthl rntliteral\">photo.jpg<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define FILE_PHOTO \"\/photo.jpg\"<\/code><\/pre>\n\n\n\n<p>We also have a variable to hold the path where the picture will be saved on the Storage Bucket on Firebase.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define BUCKET_PHOTO \"\/data\/photo.jpg\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Configuring the File<\/h4>\n\n\n\n<p>Create a <span class=\"rnthl rntliteral\">FileConfig<\/span> object to be used with the Firebase functions. It accepts the bucket path for the file and a callback function to get the file (whether it&#8217;s from the filesystem or an SD card, for example).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>FileConfig media_file(FILE_PHOTO_PATH, file_operation_callback); \/\/ Can be set later with media_file.setFile(\"\/image.png\", file_operation_callback);<\/code><\/pre>\n\n\n\n<p>Our callback function file_operation_callback() gets the file from LittleFS.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void file_operation_callback(File &amp;file, const char *filename, file_operating_mode mode){\n    \/\/ FILE_OPEN_MODE_READ, FILE_OPEN_MODE_WRITE and FILE_OPEN_MODE_APPEND are defined in this library\n    \/\/ MY_FS is defined in this example\n    switch (mode)    {\n    case file_mode_open_read:\n        myFile = LittleFS.open(filename, \"r\");\n        if (!myFile || !myFile.available()) {\n            Serial.println(\"&#091;ERROR] Failed to open file for reading\");\n        }\n        break;\n    case file_mode_open_write:\n        myFile = LittleFS.open(filename, \"w\");\n        break;\n    case file_mode_open_append:\n        myFile = LittleFS.open(filename, \"a\");\n        break;\n    case file_mode_remove:\n        LittleFS.remove(filename);\n        break;\n    default:\n        break;\n    }\n    \/\/ Set the internal FS object with global File object.\n    file = myFile;\n}<\/code><\/pre>\n\n\n\n<p>Create a global variable of type <span class=\"rnthl rntliteral\">File<\/span> called <span class=\"rnthl rntliteral\">myFile<\/span> that will be used throughout the code to refer to the file we want to upload to the filesystem.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>File myFile;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Declaring Firebase Authentication and Components<\/h4>\n\n\n\n<p>The following line creates an authentication object using the project API key, the project user email, and password.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>UserAuth user_auth(API_KEY, USER_EMAIL, USAER_PSSWORD, 3000 \/* expire period in seconds (&lt;3600) *\/);<\/code><\/pre>\n\n\n\n<p>This creates a <span class=\"rnthl rntliteral\">FirebaseApp<\/span> instance called <span class=\"rnthl rntliteral\">app<\/span> that refers to the Firebase application.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>FirebaseApp app;<\/code><\/pre>\n\n\n\n<p>The following lines set up the asynchronous communication framework for interacting with Firebase\u2019s Realtime Database. Basically, you create an SSL client using the <span class=\"rnthl rntliteral\">WiFiClientSecure<\/span> library. Then, you instantiate an Asynchronous client called <span class=\"rnthl rntliteral\">aClient<\/span> that enables secure HTTPS. This will allow you to handle network operations asynchronously.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFiClientSecure ssl_client;\nusing AsyncClient = AsyncClientClass;\nAsyncClient aClient(ssl_client);<\/code><\/pre>\n\n\n\n<p>The following line creates a&nbsp;<span class=\"rnthl rntliteral\">Storage<\/span> object called&nbsp;<span class=\"rnthl rntliteral\">storage<\/span> that represents the Firebase storage bucket.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>RealtimeDatabase Database;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">ESP32-CAM Pin Definition<\/h4>\n\n\n\n<p>The following lines define the ESP32-CAM pins. This is the definition for the ESP32-CAM AI-Thinker module. If you&#8217;re using another ESP32-CAM module, you need to modify the pin definition\u2014check this tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-camera-pin-gpios\/\">ESP32-CAM Camera Boards: Pin and GPIOs Assignment Guide<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ OV2640 camera module pins (CAMERA_MODEL_AI_THINKER)\n#define PWDN_GPIO_NUM     32\n#define RESET_GPIO_NUM    -1\n#define XCLK_GPIO_NUM      0\n#define SIOD_GPIO_NUM     26\n#define SIOC_GPIO_NUM     27\n#define Y9_GPIO_NUM       35\n#define Y8_GPIO_NUM       34\n#define Y7_GPIO_NUM       39\n#define Y6_GPIO_NUM       36\n#define Y5_GPIO_NUM       21\n#define Y4_GPIO_NUM       19\n#define Y3_GPIO_NUM       18\n#define Y2_GPIO_NUM        5\n#define VSYNC_GPIO_NUM    25\n#define HREF_GPIO_NUM     23\n#define PCLK_GPIO_NUM     22<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Other Variables<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">takeNewPhoto<\/span> variable checks if it is time to take a new photo. We&#8217;ll set it to <span class=\"rnthl rntliteral\">true<\/span>, so that it takes a picture when the board first runs.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>boolean takeNewPhoto = true;<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">taskCompleted<\/span> is a boolean variable that checks if we successfully connected to Firebase.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>bool taskCompleted = false;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">capturePhotoSaveLittleFS() Function<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">capturePhotoSaveLittleFS()<\/span> function takes a photo and saves it in the ESP32 filesystem.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Capture Photo and Save it to LittleFS\nvoid capturePhotoSaveLittleFS( void ) {\n  \/\/ Dispose first pictures because of bad quality\n  camera_fb_t* fb = NULL;\n  \/\/ Skip first 3 frames (increase\/decrease number as needed).\n  for (int i = 0; i &lt; 4; i++) {\n    fb = esp_camera_fb_get();\n    esp_camera_fb_return(fb);\n    fb = NULL;\n  }\n    \n  \/\/ Take a new photo\n  fb = NULL;  \n  fb = esp_camera_fb_get();  \n  if(!fb) {\n    Serial.println(\"Camera capture failed\");\n    delay(1000);\n    ESP.restart();\n  }  \n\n  \/\/ Photo file name\n  Serial.printf(\"Picture file name: %s\\n\", FILE_PHOTO_PATH);\n  File file = LittleFS.open(FILE_PHOTO_PATH, FILE_WRITE);\n\n  \/\/ Insert the data in the photo file\n  if (!file) {\n    Serial.println(\"Failed to open file in writing mode\");\n  }\n  else {\n    file.write(fb-&gt;buf, fb-&gt;len); \/\/ payload (image), payload length\n    Serial.print(\"The picture has been saved in \");\n    Serial.print(FILE_PHOTO_PATH);\n    Serial.print(\" - Size: \");\n    Serial.print(fb-&gt;len);\n    Serial.println(\" bytes\");\n  }\n  \/\/ Close the file\n  file.close();\n  esp_camera_fb_return(fb);\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">initWiFi() Function<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initWiFi()<\/span> function initializes Wi-Fi.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void initWiFi(){\n  WiFi.begin(ssid, password);\n  while (WiFi.status() != WL_CONNECTED) {\n    delay(1000);\n    Serial.println(\"Connecting to WiFi...\");\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">initLittleFS() Function<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initLittleFS()<\/span> function initializes the LittleFS filesystem.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void initLittleFS(){\n  if (!LittleFS.begin(true)) {\n    Serial.println(\"An Error has occurred while mounting LittleFS\");\n    ESP.restart();\n  }\n  else {\n    delay(500);\n    Serial.println(\"LittleFS mounted successfully\");\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">initCamera() Function<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">initCamera()<\/span> function initializes the ESP32-CAM.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void initCamera(){\n \/\/ OV2640 camera module\n  camera_config_t config;\n  config.ledc_channel = LEDC_CHANNEL_0;\n  config.ledc_timer = LEDC_TIMER_0;\n  config.pin_d0 = Y2_GPIO_NUM;\n  config.pin_d1 = Y3_GPIO_NUM;\n  config.pin_d2 = Y4_GPIO_NUM;\n  config.pin_d3 = Y5_GPIO_NUM;\n  config.pin_d4 = Y6_GPIO_NUM;\n  config.pin_d5 = Y7_GPIO_NUM;\n  config.pin_d6 = Y8_GPIO_NUM;\n  config.pin_d7 = Y9_GPIO_NUM;\n  config.pin_xclk = XCLK_GPIO_NUM;\n  config.pin_pclk = PCLK_GPIO_NUM;\n  config.pin_vsync = VSYNC_GPIO_NUM;\n  config.pin_href = HREF_GPIO_NUM;\n  config.pin_sscb_sda = SIOD_GPIO_NUM;\n  config.pin_sscb_scl = SIOC_GPIO_NUM;\n  config.pin_pwdn = PWDN_GPIO_NUM;\n  config.pin_reset = RESET_GPIO_NUM;\n  config.xclk_freq_hz = 20000000;\n  config.pixel_format = PIXFORMAT_JPEG;\n\n  if (psramFound()) {\n    config.frame_size = FRAMESIZE_UXGA;\n    config.jpeg_quality = 10;\n    config.fb_count = 2;\n  } else {\n    config.frame_size = FRAMESIZE_SVGA;\n    config.jpeg_quality = 12;\n    config.fb_count = 1;\n  }\n  \/\/ Camera init\n  esp_err_t err = esp_camera_init(&amp;config);\n  if (err != ESP_OK) {\n    Serial.printf(\"Camera init failed with error 0x%x\", err);\n    ESP.restart();\n  } \n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">setup()<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, initialize the Serial Monitor, Wi-Fi, LittleFS, and the camera.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void setup(){\n  Serial.begin(115200);\n  initWiFi();\n  initCamera();\n\n  Firebase.printf(\"Firebase Client v%s\\n\", FIREBASE_CLIENT_VERSION);\n\n  initLittleFS();<\/code><\/pre>\n\n\n\n<p>Configure the SSL Client.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>ssl_client.setInsecure();\nssl_client.setConnectionTimeout(1000);\nssl_client.setHandshakeTimeout(5);<\/code><\/pre>\n\n\n\n<p>The following line initializes the Firebase app with authentication and sets the <span class=\"rnthl rntliteral\">processData()<\/span> as the callback function for async results (this means that any results from the <span class=\"rnthl rntliteral\">initializeApp()<\/span> function will be handled on the <span class=\"rnthl rntliteral\">processData()<\/span> callback function).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>initializeApp(aClient, app, getAuth(user_auth), processData, \"\ud83d\udd10 authTask\");<\/code><\/pre>\n\n\n\n<p>Then, tell that you want to set the <span class=\"rnthl rntliteral\">Storage<\/span> object defined earlier as a storage for our Firebase app.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>app.getApp&lt;Storage&gt;(storage);<\/code><\/pre>\n\n\n\n<p>Check and list any files stored on the LittleFS filesystem (this step is optional).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.println(\"Listing files in LittleFS:\");\nFile root = LittleFS.open(\"\/\");\nFile file = root.openNextFile();\nwhile (file) {\n    Serial.println(file.name());\n    file = root.openNextFile();\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">loop()<\/h4>\n\n\n\n<p>The Firebase library we\u2019re using works asynchronously and with callback functions. This means that when an event happens, the corresponding assigned callback functions will run. To keep the Firebase app running, handling authentication and asynchronous tasks, we need to add <span class=\"rnthl rntliteral\">app.loop()<\/span> at the start of our <span class=\"rnthl rntliteral\">loop()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ To maintain the authentication process.\napp.loop();<\/code><\/pre>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, take a new picture and save it to the filesystem.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (takeNewPhoto) {\n  capturePhotoSaveLittleFS();\n  takeNewPhoto = false;\n}<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">app.ready()<\/span> command checks if Firebase authentication is complete and ready, we also check if it&#8217;s time to take a new picture.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (app.ready() &amp;&amp; !taskComplete &amp;&amp; takeNewPhoto){<\/code><\/pre>\n\n\n\n<p>If yes, we reset the <span class=\"rnthl rntliteral\">taskComplete<\/span> and <span class=\"rnthl rntliteral\">takeNewPhoto<\/span> variables to their original states.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>taskComplete = true;\ntakeNewPhoto = false;<\/code><\/pre>\n\n\n\n<p>We call the <span class=\"rnthl rntliteral\">capturePhotoSaveLittleFS()<\/span> function to take a picture with the ESP32-CAM and save it in the ESP32 filesystem.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>capturePhotoSaveLittleFS();<\/code><\/pre>\n\n\n\n<p>Finally, send the picture to Firebase using the <span class=\"rnthl rntliteral\">upload()<\/span> function on the <span class=\"rnthl rntliteral\">storage<\/span> object.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>storage.upload(aClient, FirebaseStorage::Parent(STORAGE_BUCKET_ID, BUCKET_PHOTO_PATH), getFile(media_file), \"image\/jpg\", processData, \"\u2b06\ufe0f  uploadTask\");<\/code><\/pre>\n\n\n\n<p>Let&#8217;s take a look at each argument of this function:<\/p>\n\n\n\n<p><span class=\"rnthl rntliteral\">aClient<\/span>: this is the Firebase asynchronous client object used to connect to Firebase.<\/p>\n\n\n\n<p><span class=\"rnthl rntliteral\">FirebaseStorage::Parent(STORAGE_BUCKET_ID, BUCKET_PHOTO_PATH)<\/span>: specifies the location in Firebase Storage where the file will be uploaded:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span class=\"rnthl rntliteral\">STORAGE_BUCKET_ID<\/span>: The unique ID of the Firebase Storage bucket<\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">BUCKET_PHOTO_PATH<\/span>: The path or folder within the bucket where the file will be stored<\/li>\n<\/ul>\n\n\n\n<p><span class=\"rnthl rntliteral\">getFile(media_file)<\/span>: the file to be uploaded, retrieved using the <span class=\"rnthl rntliteral\">getFile()<\/span> function. We defined the file previously at the start of the code.<\/p>\n\n\n\n<p><span class=\"rnthl rntliteral\">&#8220;image\/jpg&#8221;<\/span>: the MIME type of the file, indicating its format. Here, it specifies that the file is a JPEG image.<\/p>\n\n\n\n<p><span class=\"rnthl rntliteral\">processData<\/span>: the callback function that handles the result of the upload operation<\/p>\n\n\n\n<p><span class=\"rnthl rntliteral\">&#8220;uploadTask&#8221;<\/span>: a unique identifier to identify this specific task later in the <span class=\"rnthl rntliteral\">processData()<\/span> function.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">processData Function &#8211; Handling Firebase Tasks<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">processData()<\/span> function will handle all events related to Firebase operations, including uploading files to the Firebase storage.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void processData(AsyncResult &amp;aResult)\n{\n    \/\/ Exits when no result available when calling from the loop.\n    if (!aResult.isResult())\n        return;\n\n    if (aResult.isEvent())\n    {\n        Firebase.printf(\"Event task: %s, msg: %s, code: %d\\n\", aResult.uid().c_str(), aResult.appEvent().message().c_str(), aResult.appEvent().code());\n    }\n\n    if (aResult.isDebug())\n    {\n        Firebase.printf(\"Debug task: %s, msg: %s\\n\", aResult.uid().c_str(), aResult.debug().c_str());\n    }\n\n    if (aResult.isError())\n    {\n        Firebase.printf(\"Error task: %s, msg: %s, code: %d\\n\", aResult.uid().c_str(), aResult.error().message().c_str(), aResult.error().code());\n    }\n\n    if (aResult.downloadProgress())\n    {\n        Firebase.printf(\"Downloaded, task: %s, %d%s (%d of %d)\\n\", aResult.uid().c_str(), aResult.downloadInfo().progress, \"%\", aResult.downloadInfo().downloaded, aResult.downloadInfo().total);\n        if (aResult.downloadInfo().total == aResult.downloadInfo().downloaded)\n        {\n            Firebase.printf(\"Download task: %s, complete!\u2705\ufe0f\\n\", aResult.uid().c_str());\n        }\n    }\n\n    if (aResult.uploadProgress())\n    {\n        Firebase.printf(\"Uploaded, task: %s, %d%s (%d of %d)\\n\", aResult.uid().c_str(), aResult.uploadInfo().progress, \"%\", aResult.uploadInfo().uploaded, aResult.uploadInfo().total);\n        if (aResult.uploadInfo().total == aResult.uploadInfo().uploaded)\n        {\n            Firebase.printf(\"Upload task: %s, complete!\u2705\ufe0f\\n\", aResult.uid().c_str());\n            Serial.print(\"Download URL: \");\n            Serial.println(aResult.uploadInfo().downloadUrl);\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"demonstration\">Demonstration<\/h1>\n\n\n\n<p>After inserting the required credentials, upload the code to your ESP32-CAM. If you don&#8217;t know how to upload code to the ESP32-CAM, you can follow the next tutorial(s):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/program-upload-code-esp32-cam\/\">How to Program \/ Upload Code to ESP32-CAM AI-Thinker (Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/upload-code-esp32-cam-mb-usb\/\">Upload Code to ESP32-CAM AI-Thinker using ESP32-CAM-MB USB Programmer<\/a><\/li>\n<\/ul>\n\n\n\n<p>After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the ESP32-CAM on-board RST button.<\/p>\n\n\n\n<p>It will log in to Firebase, take a picture, and save it to LittleFS. Afterwards, it will upload the picture to Firebase Storage.<\/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=\"749\" height=\"705\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-With-Firebase-File-uploaded-to-firebase-success.png?resize=749%2C705&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32-CAM Upload Picture to Firebase Serial Monitor\" class=\"wp-image-172796\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-With-Firebase-File-uploaded-to-firebase-success.png?w=749&amp;quality=100&amp;strip=all&amp;ssl=1 749w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/ESP32-With-Firebase-File-uploaded-to-firebase-success.png?resize=300%2C282&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 749px) 100vw, 749px\" \/><\/figure><\/div>\n\n\n<p>Now, go to your Firebase console, and select the <strong>Storage <\/strong>tab. There should be a folder called <span class=\"rnthl rntliteral\"><em>data<\/em><\/span> that contains your picture.<\/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=\"701\" height=\"162\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Data-Folder.jpg?resize=701%2C162&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Folder Created in Firebase Storage\" class=\"wp-image-172797\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Data-Folder.jpg?w=701&amp;quality=100&amp;strip=all&amp;ssl=1 701w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/Firebase-Storage-Data-Folder.jpg?resize=300%2C69&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><\/figure><\/div>\n\n\n<p>You can check some metadata about the picture and view it in full size. You can also access the image by accessing the Download URL printed on the Serial Monitor.<\/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=\"593\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/new_file_uploaded_to_firebase_storage.png?resize=750%2C593&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Picture Uploaded to Firebase Storage Metada\" class=\"wp-image-172798\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/new_file_uploaded_to_firebase_storage.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/09\/new_file_uploaded_to_firebase_storage.png?resize=300%2C237&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 project with Storage. Firebase Storage allows you to store files in the cloud. Then, you can access those files by going to the Firebase console, or you can build a web app to display those files (check this tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-display-pictures-firebase-web-app\/\">ESP32-CAM: Display Pictures in Firebase Web App<\/a>).<\/p>\n\n\n\n<p>We&#8217;ve shown a simple example of sending a picture taken with the ESP32-CAM to the Firebase Storage. The example is as simple as possible so that you can understand the basics. The idea is to modify the project to make something useful\u2014like taking a picture and uploading it to Firebase storage when motion is detected, when a door opens, or when you press a button.<\/p>\n\n\n\n<p>We have other <strong>Firebase tutorials<\/strong> that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-realtime-database\/\">ESP32: Getting Started with Firebase (Realtime Database)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-firebase-web-app\/\">ESP32 with Firebase \u2013 Creating a Web App<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-firebase-authentication\/\">ESP32\/ESP8266: Firebase Authentication (Email and Password)<\/a><\/li>\n\n\n\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>Learn more about the ESP32-CAM with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-projects-ebook\/\"><strong>Build ESP32-CAM Projects (eBook)<\/strong><\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32-cam\/\"><strong>Read all our ESP32-CAM Projects, Tutorials and Guides<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn how to create a Firebase Web App to control outputs and monitor sensors from anywhere:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/firebase-esp32-esp8266-ebook\/\"><strong>Firebase Web App with the ESP32 and ESP8266 eBook<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<p>We hope you found this tutorial useful.<\/p>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll learn how to take and upload a picture to Firebase Storage using the ESP32-CAM. You&#8217;ll create a Firebase project with Storage that allows you to store &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32-CAM Save Picture in Firebase Storage\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-cam-save-picture-firebase-storage\/#more-107690\" aria-label=\"Read more about ESP32-CAM Save Picture in Firebase Storage\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":107712,"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":[276,281,319,264],"tags":[],"class_list":["post-107690","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","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-Storage.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\/107690","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=107690"}],"version-history":[{"count":30,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107690\/revisions"}],"predecessor-version":[{"id":219658,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/107690\/revisions\/219658"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/107712"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=107690"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=107690"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=107690"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}