This guide will teach you how to create a simple Firebase Web App to control and monitor your ESP8266 NodeMCU board. The Web App you’ll create can be accessed worldwide to control and monitor your ESP8266 from anywhere in the world. This Web App makes the bridge between the Firebase Realtime Database and the ESP8266.

Updated 22 April 2025
Complete the following tutorial before proceeding:
Here are the major steps to complete this tutorial.
- Creating Firebase Project—we recommend using the Firebase project from this previous tutorial.
- Installing Required Software
- Setting Up a Firebase Web App Project (VS Code)
- Creating Firebase Web App
We have a similar tutorial for the ESP32 board: ESP32 with Firebase – Creating a Web App
Installing Required Software
To follow this project, you need to install the following software:
Installing VS Code
Follow the next instructions to install VS Code on your Operating System:
A) Installing VS Code on Windows (Visual Studio Code)
Go to https://code.visualstudio.com/ and download the stable build for your operating system (Windows).

Click on the installation wizard to start the installation and follow all the steps to complete the installation. Accept the agreement and press the Next button.

Select the following options and click Next.

Press the Install button.

Finally, click Finish to finish the installation.

Open VS Code, and you’ll be greeted by a Welcome tab with the released notes of the newest version.

That’s it. Visual Studio Code was successfully installed.
B) Installing VS Code on Mac OS X (Visual Studio Code)
Go to https://code.visualstudio.com/ and download the stable build for your operating system (Mac OS X).

After downloading the Visual Studio Code application file, you’ll be prompted with the following message. Press the “Open” button.

Or open your Downloads folder and open Visual Studio Code.

After that, you’ll be greeted by a Welcome tab with the released notes of the newest version.

That’s it. Visual Studio Code was successfully installed.
C) Installing VS Code on Linux Ubuntu (Visual Studio Code)
Go to https://code.visualstudio.com/ and download the stable build for your operating system (Linux Ubuntu).

Save the installation file:

To install it, open a Terminal window, navigate to your Downloads folder and run the following command to install VS Code.
$ cd Downloads
~/Downloads $ sudo apt install ./code_1.49.1-1600299189_amd64.deb
When the installation is finished, VS Code should be available in your applications menu.

Open VS Code, and you’ll be greeted by a Welcome tab with the released notes of the newest version.

That’s it. Visual Studio Code was successfully installed.
Installing Node.js
1) Go to nodejs.org and download the LTS version.

2) Run the executable file and follow the installation process.
3) Enable automatically installing all the necessary tools.

4) When it’s done, click Finish.

5) A Terminal window will open to install the Additional Tools for Node.js. When it’s done, click any key to continue. When it’s finished, you can close the Terminal Window.

Installing Firebase Tools (VS Code)
1) Open VS Code. Close all opened projects, if any.
2) Open a new Terminal window. Go to Terminal > New Terminal.
3) Run the following command to change to the C:\ path (you can install it in any other path):
cd \
Before installing Firebase tools, run the following command to install the latest npm package:
npm install -g npm@latest
4) Run the following command to install firebase tools globally:
npm -g install firebase-tools

5) Firebase tools will be installed (you can ignore any warning about deprecated libraries).
6) Test if Firebase was successfully installed with the following command:
firebase --version
It should return the Firebase version currently installed.

Setting Up a Firebase Web App Project (VS Code)
Before creating the Firebase Web App, you need to set up a Firebase Project on VS Code. These are the steps:
1) Creating a Project Folder
1) Create a folder on your computer where you want to save your Firebase project—for example, Firebase-Project.
2) Open VS Code. Go to File > Open Folder… and select the folder you’ve just created.
3) Go to Terminal > New Terminal. A new Terminal window should open on your project path.

2) Firebase Login
4) On the previous Terminal window, type the following:
firebase login
5) You’ll be asked to collect CLI usage and error reporting information. Enter “n” and press Enter to deny.

6) After this, it will pop up a new window on your browser to login into your firebase account.

7) Allow Firebase CLI to access your Google account.

8) After this, Firebase CLI login should be successful. You can close the browser window.

3) Initializing Web App Firebase Project
9) After successfully login in, run the following command to start a Firebase project directory in the current folder.
firebase init
10) You’ll be asked if you want to initialize a Firebase project in the current directory. Enter Y and hit Enter.

1) Then, use they up and down arrows and the Space key to select the options. Select the following options:
- RealTime Database: Configure security rules file for Realtime Database and (optionally) provision default instance.
- Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
The selected options will show up with a green asterisk. Then, hit Enter.

12) Select the option “Use an existing project”—it should be highlighted in blue—then, hit Enter.

13) After that, select the Firebase project for this directory—it should be the project created in this previous tutorial. In my case, it is called ESP-Project. Then hit Enter.

14) Then, select the hosting options as shown below:
- What do you want to use as your public directory? Hit Enter to select public.
- Configure as a single-page app (rewrite urls to /index.html)? No
- Set up automatic builds and deploys with GitHub? No

15) Press Enter on the following question to select the default database security rules file: “What file should be used for Realtime Database Security Rules?“
16) The Firebase project should now be initialized successfully. Notice that VS Code created some essential files under your project folder.

The index.html file contains some HTML text to build a web page. For now, leave the default HTML text. The idea is to replace that with your own HTML text to build a custom web page for your needs. We’ll do that later in this tutorial.
17) To check if everything went as expected, run the following command on the VS Code Terminal window.
firebase deploy

After deploying, you should get your Hosting URL. Go to that URL. You should get access to a similar web page.

This web page is built using the files placed in the public folder of your Firebase project.
You can access that web page from anywhere in the world. Now, the idea is to change the files in the public folder to show your own web page instead of that one.
4) Add Firebase To Your App
Leave VS Code open. Meanwhile, you need to go to your Firebase account to add Firebase to your app.
18) Go to your Firebase console and select your project. Then, click on the +Add app button and then, select the web app icon.

19) Give your app a name. I simply called it test. Then, check the box next to Also set up Firebase Hosting for this App. Click Register app.

20) Then, copy the firebaseConfig object because you’ll need it later.

Click Next on the proceeding steps.
After this, you can also access the firebaseConfig object if you go to your Project settings in your Firebase console.
21) Copy the authDomain. In my case, it is (the same we got in the Terminal window after setting up the Firebase project):
https://esp-project-a9add.web.app
This is the URL that allows you to access your web app.
Creating Firebase Web App
Now that you’ve created a Firebase project app successfully on VS Code, follow the next steps to customize the app to display the values saved on the Realtime Database.
index.html
Copy the following to your index.html file. This HTML file creates a simple web page that displays the readings saved on the Realtime Database created in this previous project.
<!-- Complete Project Details
ESP32: https://RandomNerdTutorials.com/esp32-firebase-web-app/
ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-firebase-web-app/ -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP Firebase App</title>
<!-- Load your app.js script -->
<script src="app.js" type="module"></script>
</head>
<body>
<h1>ESP Firebase Web App Example</h1>
<p>Reading int: <span id="reading-int"></span></p>
<p>Reading float: <span id="reading-float"></span></p>
<p>Reading string: <span id="reading-string"></span></p>
</body>
</html>
Let’s take a quick look at the HTML file.
In the <head> of the HTML file, we must add all the required metadata.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP Firebase App</title>
<!-- Load your app.js script (place at the bottom) -->
<script src="app.js" type="module"></script>
</head>
The title of the web page is ESP Firebase App, but you can change it in the following line.
<title>ESP Firebase App</title>
We’ll take care of interacting with the Realtime Database on a JavaScript file called app.js (that we’ll create later). That file will also contain the JavaScript functions to update the HTML page with the database values. We need to load it here before displaying the body of the HTML page.
<script src="app.js" type="module"></script>
Now, let’s go to the HTML parts that are visible to the user—go between the <body> and </body> tags.
We create a heading with the following text: ESP Firebase Web App Example, but you can change it to whatever you want.
<h1>ESP Firebase Web App Example</h1>
Then, we add three paragraphs to display the int, float, and String values saved in the database. We create <span> tags with specific ids, so that we can refer to those HTML elements using JavaScript and insert the database values.
<p>Reading int: <span id="reading-int"></span></p>
<p>Reading float: <span id="reading-float"></span></p>
<p>Reading string: <span id="reading-string"></span></p>
After making the necessary changes, you can save the HTML file.
app.js
Inside the public folder, create a file called app.js. You can do this on VS Code by selecting the public folder and then clicking on the +file icon. This JavaScript file is responsible for interacting with the Realtime Database and updating the values on the web page whenever there’s a change in the database.
Copy the following to your app.js file and save it.
// Complete Project Details
// ESP32: https://RandomNerdTutorials.com/esp32-firebase-web-app/
// ESP8266: https://RandomNerdTutorials.com/esp8266-nodemcu-firebase-web-app/
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js";
import { getDatabase, ref, onValue } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-database.js";
// Firebase configuration
const firebaseConfig = {
apiKey: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
authDomain: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
databaseURL: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
projectId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
storageBucket: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
messagingSenderId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
appId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Get a reference to the database
const database = getDatabase(app);
// Database Paths
const dataFloatPath = 'test/float';
const dataIntPath = 'test/int';
const dataStringPath = 'test/string';
// Get database references
const databaseFloatRef = ref(database, dataFloatPath);
const databaseIntRef = ref(database, dataIntPath);
const databaseStringRef = ref(database, dataStringPath);
// Variables to save database current values
let floatReading;
let intReading;
let stringReading;
// Attach listeners
onValue(databaseFloatRef, (snapshot) => {
floatReading = snapshot.val();
console.log("Float reading: " + floatReading);
document.getElementById("reading-float").innerHTML = floatReading;
});
onValue(databaseIntRef, (snapshot) => {
intReading = snapshot.val();
console.log("Int reading: " + intReading);
document.getElementById("reading-int").innerHTML = intReading;
});
onValue(databaseStringRef, (snapshot) => {
stringReading = snapshot.val();
console.log("String reading: " + stringReading);
document.getElementById("reading-string").innerHTML = stringReading;
});
Let’s take a quick look to see how it works.
Importing Firebase Libraries
The following lines load the Firebase tools that will be required for this example to connect and read from the Realtime Database. We use the Firebase CDN URLs, so we don’t need to install Firebase locally.
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js";
import { getDatabase, ref, onValue } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-database.js";
Firebase Configuration
Add your firebaseConfig object below. This is required to authenticate and locate the RTDB of your project. You get these values from the Firebase Console when you create a project and add a web app (like we did in previous steps).
const firebaseConfig = {
apiKey: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
authDomain: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
databaseURL: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
projectId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
storageBucket: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
messagingSenderId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION",
appId: "REPLACE_WITH_YOUR_Firebase_CONFIGURATION"
};
Initialize Firebase
The following line initializes a Firebase app using the configuration object defined earlier. It returns an app object that you can use to interact with the application.
const app = initializeApp(firebaseConfig);
Reference to the Database, Database Paths, and Other Variables
The following command creates a reference to the Database associated with the app we initialized.
const database = getDatabase(app);
We define the database paths where the data we want to read is stored.
const dataFloatPath = 'test/float';
const dataIntPath = 'test/int';
const dataStringPath = 'test/string';
Then, we create references to specific locations on the database using those paths.
const databaseFloatRef = ref(database, dataFloatPath);
const databaseIntRef = ref(database, dataIntPath);
const databaseStringRef = ref(database, dataStringPath);
We create variables to store the current values read from the database.
let floatReading;
let intReading;
let stringReading;
Get Values from the Database (Listeners)
Finally, to get values from the database, we can attach listeners to each of those database references. Then, anytime there’s a change in the database, we’ll update the HTML page with the corresponding values.
Let’s see how to do that. For example, we can use the onValue() function that accepts as arguments a reference to the database, and a callback function:
onValue(databaseFloatRef, (snapshot) => {
floatReading = snapshot.val();
console.log("Float reading: " + floatReading);
document.getElementById("reading-float").innerHTML = floatReading;
});
In this case, the onValue() function attaches a listener to the databaseFloatRef (/test/float). Whenever the value at that path changes in the database, the callback function runs. In this case, we’re defining the callback function inside the onValue(). It is defined as an arrow function.
The (snapshot) is the parameter of the callback function. When Firebase calls the callback, it passes a snapshot object containing the current data at test/float. Then, the => arrow syntax indicates this is an arrow function, a concise way to define functions in JavaScript. The function body is defined between { }.
Let’s go back to the callback function: snapshot.val() gets the current value at the path. The value is stored in the floatReading variable.
floatReading = snapshot.val();
It’s logged to the console for debugging purposes.
console.log("Float reading: " + floatReading);
The webpage element with id=”reading-float” (defined in the index.html file) is updated to display the value.
document.getElementById("reading-float").innerHTML = floatReading;
We proceed in a similar way for the other database paths.
onValue(databaseIntRef, (snapshot) => {
intReading = snapshot.val();
console.log("Int reading: " + intReading);
document.getElementById("reading-int").innerHTML = intReading;
});
onValue(databaseStringRef, (snapshot) => {
stringReading = snapshot.val();
console.log("String reading: " + stringReading);
document.getElementById("reading-string").innerHTML = stringReading;
});
Deploy your App
After saving the HTML and JavaScript files, deploy your app on VS Code by running the following command.
firebase deploy
ESP8266 Arduino Sketch
Upload the following code to your ESP8266. This is the same code used in this previous project to write to the database. This code simply writes to the database every 10 seconds.
Don’t forget to insert your network credentials, database URL, and Firebase Project API Key.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp8266-nodemcu-firebase-realtime-database/
*********/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <FirebaseClient.h>
// Network and Firebase credentials
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
#define Web_API_KEY "REPLACE_WITH_YOUR_FIREBASE_PROJECT_API_KEY"
#define DATABASE_URL "REPLACE_WITH_YOUR_FIREBASE_DATABASE_URL"
#define USER_EMAIL "REPLACE_WITH_FIREBASE_PROJECT_EMAIL_USER"
#define USER_PASS "REPLACE_WITH_FIREBASE_PROJECT_USER_PASS"
// User function
void processData(AsyncResult &aResult);
// Authentication
UserAuth user_auth(Web_API_KEY, USER_EMAIL, USER_PASS);
// Firebase components
FirebaseApp app;
WiFiClientSecure ssl_client;
using AsyncClient = AsyncClientClass;
AsyncClient aClient(ssl_client);
RealtimeDatabase Database;
// Timer variables for sending data every 10 seconds
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 10000; // 10 seconds in milliseconds
// Variables to send to the Database
int intValue = 0;
float floatValue = 0.01;
String stringValue = "";
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(300);
}
Serial.println();
// Configure SSL client
ssl_client.setInsecure();
ssl_client.setTimeout(1000); // Set connection timeout
ssl_client.setBufferSizes(4096, 1024); // Set buffer sizes
// Initialize Firebase
initializeApp(aClient, app, getAuth(user_auth), processData, "🔐 authTask");
app.getApp<RealtimeDatabase>(Database);
Database.url(DATABASE_URL);
}
void loop(){
// Maintain authentication and async tasks
app.loop();
// Check if authentication is ready
if (app.ready()){
// Periodic data sending every 10 seconds
unsigned long currentTime = millis();
if (currentTime - lastSendTime >= sendInterval){
// Update the last send time
lastSendTime = currentTime;
// send a string
stringValue = "value_" + String(currentTime);
Database.set<String>(aClient, "/test/string", stringValue, processData, "RTDB_Send_String");
// send an int
Database.set<int>(aClient, "/test/int", intValue, processData, "RTDB_Send_Int");
intValue++; //increment intValue in every loop
// send a string
floatValue = 0.01 + random (0,100);
Database.set<float>(aClient, "/test/float", floatValue, processData, "RTDB_Send_Float");
}
}
}
void processData(AsyncResult &aResult){
if (!aResult.isResult())
return;
if (aResult.isEvent())
Firebase.printf("Event task: %s, msg: %s, code: %d\n", aResult.uid().c_str(), aResult.eventLog().message().c_str(), aResult.eventLog().code());
if (aResult.isDebug())
Firebase.printf("Debug task: %s, msg: %s\n", aResult.uid().c_str(), aResult.debug().c_str());
if (aResult.isError())
Firebase.printf("Error task: %s, msg: %s, code: %d\n", aResult.uid().c_str(), aResult.error().message().c_str(), aResult.error().code());
if (aResult.available())
Firebase.printf("task: %s, payload: %s\n", aResult.uid().c_str(), aResult.c_str());
}
Demonstration
The ESP8266 should be sending new readings every 10 seconds to the database.

Go to your App URL. You’ll see the readings being updated every 15 seconds. The App updates the web page any time the ESP8266 writes a new value.

In your Firebase Console, you can go to your project page and check that new values are being written into the database every 10 seconds.

Congratulations! You’ve created a Firebase Web App to interface with the ESP8266.
Wrapping Up
In this tutorial, you learned how to create a Firebase Web App to interface with the ESP8266. You’ve learned how to use Firebase Hosting services and the Realtime Database.
We’ve built a simple example to get you started with Firebase. It simply displays some random numbers on a web page. The idea is to replace those numbers with sensor readings or GPIO states. Additionally, you may also add buttons, or sliders to the web page to control the ESP8266 GPIOs. The possibilities are endless.
The example has some limitations but allows you to understand Firebase Web Apps potential for the ESP8266. For example, at this point, anyone can write and read data from your database because we haven’t set any database rules (it is in test mode). Additionally, we didn’t protect it with any kind of authentication. Nonetheless, we hope you find this tutorial useful. And if you want to learn more you can also check the Firebase documentation.
We hope you find this tutorial useful. If you want to learn more about Firebase with the ESP32 and ESP8266 boards, check out our new eBook:
Learn more about the ESP8266 with our resources:
- Home Automation Using ESP8266
- Build Web Servers with ESP32 and ESP8266 eBook (3rd Edition)
- More ESP8266 Projects and Tutorials…
Thanks for reading.
Great job, very interesting and perfectly translated with google. I hope to see more tutorials in the future. Thank you
I am getting an error when running “Firebase init” in VS code, and don’t know how to fix the problem. The error comes right after writing to “.firebaserc”. This file is created but it is empty. I also seem to be missing the file “.getignore”. I don’t know what went wrong or what I should look for to fix the error. Can anyone suggest what is wrong or how to fix this errord?
Hi.
What is exactly the error that you get?
Regards,
Sara
npm : The term ‘npm’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
You give complete guideline. Thanks a lot . And you also need to provide date cause there is updated version are there in firebase and Arduino IDE that makes too trouble to run project
hello i copied everything you said but im getting this error:
Token info: type = id token (GITKit token), status = on request
Token info: type = id token (GITKit token), status = error
Token error: code: -4, message: connection lost