Control ESP32/ESP8266 GPIOs from Anywhere (Firebase Web App).

In this overview, you’ll develop a Firebase Web App to regulate the ESP32 or ESP8266 GPIOs from anywhere. The access to the web application is protected with authentication using email and also password. The GPIO states are minimized the Firebase Realtime Database. The internet app writes to the database to transform the GPIO states and the ESP boards are paying attention for database changes to upgrade the GPIO states as necessary.

Control ESP32 or ESP8266 NodeMCU GPIOs from Anywhere Firebase Web App

This short article is Part 2 of a previous tutorial. You require to finish among the complying with tutorials before proceeding:

Project Overview

In this tutorial (Part 2), you’ll develop an internet app to control the ESP32 or ESP8266 GPIOs from anywhere. In a previous tutorial, you discovered how to set the ESP32 or ESP8266 to listen to database modifications as well as upgrade its GPIOs accordingly. You transformed the GPIO states manually on the Realtime Database making use of the Firebase console. Currently, you’ll develop your very own internet app, organized on Firebase, to control your boards from anywhere.

The adhering to layout shows a high-level introduction of the task we’ll construct– setting and configuring the esp32/esp8266 up the Firebase Project was done in Part 1:

Firebase Web App control ESP32 ESP8266 Outputs from Anywhere
  • Firebase hosts your web app over a global CDN using Firebase Hosting and provides an SSL certificate. You can access your web app from anywhere using the Firebase-generated domain name.
  • When you first access the web app, you need to authenticate with an authorized email address and password. You already set up that user and the authentication method in Part 1.
  • After authentication, you can access a web app page that shows several buttons to change the GPIO states on the database.
  • The ESP32 or ESP8266 is listening to database changes. When you click on the buttons, the GPIO states change on the database, and the ESP updates the states accordingly.
  • The web app also shows what’s the current state of the GPIOs.
  • As an example, we’ll control three GPIOs (12, 13, and 14). As mentioned in the previous tutorial, you can add/remove more GPIOs and boards or control other GPIOs.
  • Once you’re logged in, you can logout any time. The next time you’ll access the app you’ll need to login again.

The following screenshot shows what the websites looks like on a computer system internet browser.

Control ESP GPIOs from Anywhere Web App

Prerequisites

Before beginning creating the Firebase Web App, you need to inspect the complying with prerequisites.

Creating a Firebase Project

You ought to have followed the one the adhering to tutorials initially:

The ESP32/ESP8266 have to be running the code given because tutorial. The realtime database and authentication need to be set up likewise as displayed in the tutorial.

Install Required Software

Before starting you need to set up the called for software application to develop the Firebase Web App. Here’s a listing of the software program you require to mount (click on the web links for instructions):


1) Add an App to Your Firebase Project

1) Go to your Firebase task Console and also add an application to your task by clicking the +Add app button.

Firebase Add App to Project

2) Select the internet app icon.

Firebase Add Web App to Project

3) Give your application a name. Inspect the box following to √ Also set up Firebase Hosting for this App. Click Register app.

Firebase Add Web App to Project Hosting

4) Then, duplicate the firebaseConfig item and save it since you’ll require it later on.

firebaseConfig object configuration copy save

After this, you can also access the firebaseConfig things if you most likely to your Project settings in your Firebase console.

5) Click Next on the case steps, as well as ultimately on Continue to gaming console.


2) Setting Up a Firebase Web App Project (VS Code)

Follow the following actions to produce a Firebase Web App Project making use of VS Code.

1) Creating a Project Folder

1) Create a folder on your computer where you intend to conserve your Firebase project– for instance, Firebase-Project on the Desktop.

2) Open VS Code. Go to File > > Open Folder… … and select the folder you’ve simply produced.

3) Go to Terminal > > New Terminal. A brand-new Terminal home window should open on your job path.

Install Firebase Tools 2

2) Firebase Login

4) On the previous Terminal home window, type the following:

firebase login

5) You’ll be asked to collect CLI use and also mistake reporting info. Get in “n” as well as press Enter to refute.

Login Firebase VS Code Terminal Window

Note: If you are currently visited, it will certainly reveal a message claiming: “Already logged in as “.

6) After this, it will turn up a brand-new window on your internet browser to login right into your firebase account.

Login Firebase Account

7) Allow Firebase CLI to access your google account.

Login Firebase Account allow Firebase CLI

8) After this, Firebase CLI login ought to be successful. You can shut the internet browser window.

Login Firebase Account allow Firebase CLI Login Successful

3) Initializing Web App Firebase Project

9) After efficiently login in, run the adhering to command to start a Firebase project directory in the existing folder.

firebase init

10) You’ll be asked if you wish to boot up a Firebase job in the existing directory site. Get in Y and also struck Enter.

Login Firebase Account allow Firebase CLI firebase init

11) Then, use up as well as down arrows as well as the Space secret to choose the choices. Select the complying with choices:

  • 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 picked choices will appear with a green asterisk. Struck Enter.

Login Firebase Account allow Firebase CLI configure directory

12) Select the alternative “Use an existing project”– it needs to be highlighted in blue– then, hit Enter.

Firebase Project Setup VS Code

13) After that, pick the Firebase job for this directory site– it should be the task created partially 1. In my case, it is called esp-firebase-demo. Hit Enter.

Firebase Project VS Code create project

14) Press Enter on the following question to pick the default database security policies file: “What documents should be used for Realtime Database Security Rules?”

15) Then, pick the holding alternatives as revealed 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
Firebase initialization complete

16) The Firebase project ought to currently be initialized successfully. Notice that VS code produced some essential data under your task folder.

Firebase Project Files Created successfully

The index.html file consists of some HTML text to develop a web page. For currently, leave the default HTML message. The suggestion is to replace that with your own HTML text to develop a personalized web page for your demands. We’ll do that later on in this tutorial.

17) To examine if whatever went as expected, run the adhering to command on the VS Code Terminal window.

firebase deploy
Firebase App First Deploy Testing

You must obtain a Deploy total! message and also an URL to the Project Console and the Hosting URL.

18) Copy the hosting URL and also paste it right into a web browser window. You ought to see the following website. You can access that websites from anywhere in the globe.

Firebase test page hosting setup complete

The web page you’ve seen formerly is built with the HTML data placed in the public folder of your Firebase project. By transforming the web content of that documents, you can produce your own internet application. That’s what we’re going to perform in the next section.


3) Creating Firebase Web App

Now that you’ve developed a Firebase project application efficiently on VS Code, comply with the following actions to personalize the application to display the sensor readings on a login-protected web page.

index.html

Copy the following to your index.html documents. This HTML documents creates a basic internet page with ON as well as OFF switches to manage GPIOs 12, 13, and also 14.

If you aren’t confirmed, it reveals a login type. When you validate with an authorized individual email as well as equivalent password, it shows the interface with the buttons.

<!DOCTYPE html>
<!-- Complete Project Details at: https://RandomNerdTutorials.com/ -->
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>ESP IoT Firebase App</title>

    <!-- update the version number as needed -->
    <script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-app.js"></script>

    <!-- include only the Firebase features as you need -->
    <script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-database.js"></script>

    <script>
      // REPLACE WITH YOUR web app's Firebase configuration
      const firebaseConfig = {
        apiKey: "",
        authDomain: "",
        databaseURL: "",
        projectId: "",
        storageBucket: "",
        messagingSenderId: "",
        appId: ""
      };

      // Initialize firebase
      firebase.initializeApp(firebaseConfig);

      // Make auth and database references
      const auth = firebase.auth();
      const db = firebase.database();

    </script>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    <link rel="icon" type="image/png" href="favicon.png">
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <!--TOP BAR-->
  <div class="topnav">
    <h1>ESP GPIO Control <i class="fas fa-lightbulb"></i></h1>
  </div>

  <!--AUTHENTICATION BAR (USER DETAILS/LOGOUT BUTTON)-->
  <div id="authentication-bar" style="display: none;">
    <p><span id="authentication-status">User logged in</span>
       <span id="user-details">USEREMAIL</span>
       <a href="/" id="logout-link">(logout)</a>
    </p>
  </div>

  <!--LOGIN FORM-->
  <form id="login-form" style="display: none;">
    <div class="form-elements-container">
      <label for="input-email"><b>Email</b></label>
      <input type="text" placeholder="Enter Username" id="input-email" required>

      <label for="input-password"><b>Password</b></label>
      <input type="password" placeholder="Enter Password" id="input-password" required>

      <button type="submit" id="login-button">Login</button>
      <p id="error-message" style="color:red;"></p>
    </div>
  </form>

  <!--CONTENT (SENSOR READINGS)-->
  <div class="content-sign-in" id="content-sign-in" style="display: none;">
    <div class="card-grid">
      <!--CARD FOR GPIO 12-->
      <div class="card">
        <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 12</p>
        <p>
          <button class="button-on" id="btn1On">ON</button>
          <button class="button-off" id="btn1Off">OFF</button>
        </p>
        <p class="state">State:<span id="state1"></span></p>
      </div>

      <!--CARD FOR GPIO 13-->
      <div class="card">
        <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 13</p>
        <p>
          <button class="button-on" id="btn2On">ON</button>
          <button class="button-off" id="btn2Off">OFF</button>
        </p>
        <p class="state">State:<span id="state2"></span></p>
      </div>

      <!--CARD FOR GPIO 14-->
      <div class="card">
        <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 14</p>
        <p>
          <button class="button-on" id="btn3On">ON</button>
          <button class="button-off" id="btn3Off">OFF</button>
        </p>
        <p class="state">State:<span id="state3"></span></p>
      </div>
    </div>
  </div>
    <script src="scripts/auth.js"></script>
    <script src="scripts/index.js"></script>
  </body>
</html>

You need to change the code with your very own firebaseConfig object– the one you’ve got.

How it Works

Let’s take a quick look at the HTML data, or miss to the following area.

In the << head> > of the HTML file, we should add all the needed metadata.

The title of the websites is ESP Firebase App, however you can transform it in the adhering to line.

<title>ESP Firebase App</title>

You need to include the adhering to line to be able to use Firebase with your app.

<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>

You should additionally include any kind of Firebase products you wish to make use of. In this example, we’re utilizing the Realtime Database and Authentication.

<script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-database.js"></script>

Then, change the firebaseConfig things with the one you’ve obtained.

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"
};

Finally, Firebase is booted up, and we create two international variables db as well as auth that refer to Firebase authentication as well as to Firebase realtime data source.

// Initialize firebase
firebase.initializeApp(firebaseConfig);
      
// Make auth and database references
const auth = firebase.auth();
const db = firebase.database();

The complying with line enables us to make use of:

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

The following consists of a on our websites.

<link rel="icon" type="image/png" href="favicon.png">

Finally, reference an outside style.css documents to style the HTML page.

<link rel="stylesheet" type="text/css" href="style.css">

We’re done with the metadata. Currently, allow’s go to the HTML parts that show up to the customer– go between the << body> > as well as < tags.

We develop a top “navigation” bar with the name of our app and a small symbol from fontawesome.

<!--TOP BAR-->
<div class="topnav">
  <h1>ESP GPIO Control <i class="fas fa-lightbulb"></i></h1>
</div>

The following lines develop a bar with the details of the confirmed individual (e-mail). It likewise reveals a logout web link to log out the customer.

<div id="authentication-bar" style="display: none;">
  <p><span id="authentication-status">User logged in</span>
     <span id="user-details">USEREMAIL</span>
     <a href="/" id="logout-link">(logout)</a>
  </p>
</div>

First, we set the display style of all elements to none. We’ll hide as well as show content depending if the customer is confirmed or otherwise– we’ll take care of that making use of JavaScript.

Next, the complying with lines create the login kind with an input field for the email and an input area for the password:

<form id="login-form" style="display: none;">  
  <div class="form-elements-container">
    <label for="input-email"><b>Email</b></label>
    <input type="text" placeholder="Enter Username" id="input-email" required>
  
    <label for="input-password"><b>Password</b></label>
    <input type="password" placeholder="Enter Password" id="input-password" required>
          
    <button type="submit" id="login-button">Login</button>
    <p id="error-message" style="color:red;"></p>
  </div>
</form>

Inside the kind, there’s likewise a paragraph to display a mistake message if the login falls short.

<p id="error-message" style="color:red;"></p>

Finally, we create a grid to present various cards for the GPIOs.

<div class="content-sign-in" id="content-sign-in" style="display: none;">
  <div class="card-grid">

For example, the adhering to lines create a card for GPIO 12:

<!--CARD FOR GPIO 12-->
<div class="card">
  <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 12</p>
  <p>
    <button class="button-on" id="btn1On">ON</button>
    <button class="button-off" id="btn1Off">OFF</button>
  </p>
  <p class="state">State:<span id="state1"></span></p>
</div>

The switches have certain ids so that we can describe them later in the Javascript data. There’s likewise a period tag with a details id to insert the GPIO state.

Creating the cards for the various other GPIOs is comparable:

<!--CARD FOR GPIO 13-->
<div class="card">
  <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 13</p>
  <p>
    <button class="button-on" id="btn2On">ON</button>
    <button class="button-off" id="btn2Off">OFF</button>
  </p>
  <p class="state">State:<span id="state2"></span></p>
</div>

<!--CARD FOR GPIO 14-->
<div class="card">
  <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 14</p>
  <p>
    <button class="button-on" id="btn3On">ON</button>
    <button class="button-off" id="btn3Off">OFF</button>
  </p>
  <p class="state">State:<span id="state3"></span></p>
</div>

It’s essential to bear in mind the ids of each of those components, so that’s its less complicated to determine them on the JavaScript data. You can utilize any kind of various other ids that make feeling for your job.

GPIO 12 GPIO 13 GPIO 14
ON Button btn1On btn2On btn3On
OFF Button btn1Off btn2Off btn3Off
State state1 state2 state3

Finally, we require to include recommendations to the outside JavaScript files. For our application, we’ll develop 2 JavaScript data: auth.js (that deals with every little thing associated to the verification) as well as index.js that handles whatever related to the UI. We’ll produce those data inside a folder called scripts inside the public folder of our application.

<script src="scripts/auth.js"></script>
<script src="scripts/index.js"></script>

After making the essential changes (putting your firebaseConfig item), you can conserve the HTML documents.

style.css

Inside the general public folder develop a data called style.css. To develop the file, choose the general public folder, and after that click on the +file symbol on top of the File Explorer. Call it style.css.

Create CSS File VS Code

Then, replicate the complying with to the style.css file

html {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    display: inline-block;
    text-align: center;
}
h1 {
    font-size: 1.8rem;
    color: white;
}
.topnav {
    overflow: hidden;
    background-color: #049faa;
    color: white;
    font-size: 1rem;
    padding: 10px;
}
#authentication-bar{
    background-color:mintcream;
    padding-top: 10px;
    padding-bottom: 10px;
}

#user-details{
    color: cadetblue;
}

.content {
    padding: 20px;
}

body {
    margin: 0;
}

.card-grid {
    max-width: 800px;
    margin: 0 auto;
    display: grid;
    grid-gap: 2rem;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.card {
    background-color: white;
    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}

.card-title {
    font-size: 1.2rem;
    color: #034078
}
.state {
    color:#1282A2;
}
button {
    background-color: #049faa;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    cursor: pointer;
    border-radius: 4px;
}
.button-on {
    background-color:#034078;
}
.button-on:hover {
    background-color: #1282A2;
}
.button-off {
    background-color:#858585;
}
.button-off:hover {
    background-color: #252524;
}

.form-elements-container{
    padding: 16px;
    width: 250px;
    margin: 0 auto;
}

input[type=text], input[type=password] {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    box-sizing: border-box;
}

The CSS file includes some straightforward designs to make our page look far better. We will not go over how CSS operates in this tutorial. You can easily modify the CSS documents to transform the shades and also font style dimension.

JavaScript Files

We’ll create 2 JavaScript data (index.js and also auth.js) inside a manuscripts folder inside the public folder.

  • Select the public folder, then click on the +folder icon to create a new folder. Call scripts to that new folder.
  • Then, select the scripts folder and click on the +file icon. Create a file called auth.js. Then, repeat the previous steps to create an index.js.

The following image demonstrates how your web app project folder structure need to look like.

Firebase Project VS Code Folder File Structure

auth.js

Now allow’s apply customer sign-in using Firebase authentication. We’ll implement sign-in using e-mail and password.

Copy the following to the auth.js file you produced formerly.

document.addEventListener("DOMContentLoaded", function(){

    // listen for auth status changes
    auth.onAuthStateChanged(user => {
        if (user) {
            console.log("user logged in");
            console.log(user);
            setupUI(user);
        } else {
            console.log("user logged out");
            setupUI();
        }
    });

    // login
    const loginForm = document.querySelector('#login-form');
    loginForm.addEventListener('submit', (e) => {
        e.preventDefault();
        // get user info
        const email = loginForm['input-email'].value;
        const password = loginForm['input-password'].value;
        // log the user in
        auth.signInWithEmailAndPassword(email, password).then((cred) => {
            // close the login modal & reset form
            loginForm.reset();
            console.log(email);
        })
        .catch((error) =>{
            const errorCode = error.code;
            const errorMessage = error.message;
            document.getElementById("error-message").innerHTML = errorMessage;
            console.log(errorMessage);
        });
    });

    // logout
    const logout = document.querySelector('#logout-link');
    logout.addEventListener('click', (e) => {
    e.preventDefault();
    auth.signOut();
    });
    
});

Then, save the file. This documents cares for everything relevant to the login and logout of the individual. Continue reading to discover exactly how the code works or skip to the next area.

Login

The adhering to lines are accountable for visiting the user.

const loginForm = document.querySelector('#login-form');
loginForm.addEventListener('submit', (e) => {
  e.preventDefault();
  // get user info
  const email = loginForm['input-email'].value;
  const password = loginForm['input-password'].value;
  // log the user in
  auth.signInWithEmailAndPassword(email, password).then((cred) => {
    // close the login modal & reset form
    loginForm.reset();
    console.log(email);
  })
  .catch((error) =>{
    const errorCode = error.code;
    const errorMessage = error.message;
    document.getElementById("error-message").innerHTML = errorMessage;
    console.log(errorMessage);
  });
});

We produce a variable that refers to the login form HTML element called loginForm.

const loginForm = document.querySelector('#login-form');

If you go back to the index.html file, you can see that the type has the login-form id.

We include an occasion audience of type submit to the form. This suggests that the succeeding instructions will certainly run whenever the form is sent.

loginForm.addEventListener('submit', (e) => {

You can obtain the submitted data as follows.

const email = loginForm['input-email'].value;
const password = loginForm['input-password'].value;

If you return to the HTML data, you’ll see that the input fields include the adhering to ids: input-email and input-password for the e-mail and password, specifically.

Now that we have the placed e-mail as well as password, we can try to visit to Firebase. To do that, pass the user’s e-mail address as well as password to the complying with method: signInWithEmailAndPassword:

auth.signInWithEmailAndPassword(email, password).then((cred) => {

After logging in, we reset the kind as well as print the individual email in the console.

auth.signInWithEmailAndPassword(email, password).then((cred) => {
  // close the login modal & reset form
  loginForm.reset();
  console.log(email);
})

In situation there is a mistake signing in, we capture the mistake message, and also present it on the error-message HTML aspect (a paragraph below the kind).

.catch((error) =>{
  const errorCode = error.code;
  const errorMessage = error.message;
  document.getElementById("error-message").innerHTML = errorMessage;
  console.log(errorMessage);
});

Logout

The complying with fragment is accountable for logging out the individual.

const logout = document.querySelector('#logout-link');
logout.addEventListener('click', (e) => {
  e.preventDefault();
  auth.signOut();
});

When the user is visited, a logout web link shows up in the authentication bar. That link has the logout-link id (see on the HTML documents). Initially, we develop a variable called logout that refers to the logout link.

const logout = document.querySelector('#logout-link');

Then, we add an occasion audience of type click. This suggests the subsequent instructions will run whenever you click on the logout web link.

logout.addEventListener('click', (e) => {

When the button is clicked, we sign out the user using the signOut approach.

auth.signOut();

Auth State Changes

To maintain track of the customer verification state– to understand if the user is visited or logged out, there is a method called onAuthSateChanged that enables you to get an occasion whenever the authentication state adjustments.

auth.onAuthStateChanged(user => {
  if (user) {
    console.log("user logged in");
    console.log(user);
    setupUI(user);
    var uid = user.uid;
    console.log(uid);
  } else {
    console.log("user logged out");
    setupUI();
  }
});

If the customer returned is null, the customer is presently signed out. Or else, it is presently authorized in.

In both situations, we publish the current customer state to the console and call the setupUI() function. We have not developed that feature yet (we’ll produce it in the next section), but it will certainly be accountable for taking care of the interface as necessary to the verification state.

When the user is logged in, we pass the customer as a debate to the setupUI() function. In this instance, we’ll present the full interface to show the buttons to regulate the GPIOs, as you’ll see later on.

if (user) {
  console.log("user logged in");
  console.log(user);
  setupUI(user);

If the customer is logged out, we call the setupUI() function with no argument. In that situation, we’ll simply show a message informing that the individual is logged out and does not have access to the user interface (as we’ll see later on).

} else {
  console.log("user logged out");
  setupUI();
}

index.js

The index.js file manages the UI – – it reveals the appropriate web content relying on the customer verification standing. When the user is logged in, it gets the GPIO states from the data source and also updates the GPIO states on the user interface. It transforms the states whenever you press the buttons.

Copy the complying with to the index.js file.

const loginElement = document.querySelector('#login-form');
const contentElement = document.querySelector("#content-sign-in");
const userDetailsElement = document.querySelector('#user-details');
const authBarElement = document.querySelector("#authentication-bar");

// Elements for GPIO states
const stateElement1 = document.getElementById("state1");
const stateElement2 = document.getElementById("state2");
const stateElement3 = document.getElementById("state3");

// Button Elements
const btn1On = document.getElementById('btn1On');
const btn1Off = document.getElementById('btn1Off');
const btn2On = document.getElementById('btn2On');
const btn2Off = document.getElementById('btn2Off');
const btn3On = document.getElementById('btn3On');
const btn3Off = document.getElementById('btn3Off');

// Database path for GPIO states
var dbPathOutput1 = 'board1/outputs/digital/12';
var dbPathOutput2 = 'board1/outputs/digital/13';
var dbPathOutput3 = 'board1/outputs/digital/14';

// Database references
var dbRefOutput1 = firebase.database().ref().child(dbPathOutput1);
var dbRefOutput2 = firebase.database().ref().child(dbPathOutput2);
var dbRefOutput3 = firebase.database().ref().child(dbPathOutput3);

// MANAGE LOGIN/LOGOUT UI
const setupUI = (user) => {
  if (user) {
    //toggle UI elements
    loginElement.style.display = 'none';
    contentElement.style.display = 'block';
    authBarElement.style.display ='block';
    userDetailsElement.style.display ='block';
    userDetailsElement.innerHTML = user.email;

    //Update states depending on the database value
    dbRefOutput1.on('value', snap => {
        if(snap.val()==1) {
            stateElement1.innerText="ON";
        }
        else{
            stateElement1.innerText="OFF";
        }
    });
    dbRefOutput2.on('value', snap => {
        if(snap.val()==1) {
            stateElement2.innerText="ON";
        }
        else{
            stateElement2.innerText="OFF";
        }
    });
    dbRefOutput3.on('value', snap => {
        if(snap.val()==1) {
            stateElement3.innerText="ON";
        }
        else{
            stateElement3.innerText="OFF";
        }
    });

    // Update database uppon button click
    btn1On.onclick = () =>{
        dbRefOutput1.set(1);
    }
    btn1Off.onclick = () =>{
        dbRefOutput1.set(0);
    }

    btn2On.onclick = () =>{
        dbRefOutput2.set(1);
    }
    btn2Off.onclick = () =>{
        dbRefOutput2.set(0);
    }

    btn3On.onclick = () =>{
        dbRefOutput3.set(1);
    }
    btn3Off.onclick = () =>{
        dbRefOutput3.set(0);
    }

  // if user is logged out
  } else{
    // toggle UI elements
    loginElement.style.display = 'block';
    authBarElement.style.display ='none';
    userDetailsElement.style.display ='none';
    contentElement.style.display = 'none';
  }
}

Continue checking out to discover exactly how the code functions or miss to the following area.

Getting HTML Elements

First, we produce variables to describe a number of aspects on the UI interface by describing their ids. To recognize these aspects, we recommend that you take an appearance at the HTML file supplied as well as find the aspects with the referred ids.

const loginElement = document.querySelector('#login-form');
const contentElement = document.querySelector("#content-sign-in");
const userDetailsElement = document.querySelector('#user-details');
const authBarElement = document.querySelector("#authentication-bar");

The loginElement represents the login type. When the customer is logged in (that shows the sensor analyses), the contentElement matches to the section of the web page that is visible. The userDetailsElement corresponds to a section that will certainly display the email of the logged in customer. The auhtBarElement matches to the authentication bar that shows the existing user condition, the email of the validated customer as well as the logout web link.

The complying with develops variables to describe the buttons as GPIOs states on the user interface:

// Elements for GPIO states
const stateElement1 = document.getElementById("state1");
const stateElement2 = document.getElementById("state2");
const stateElement3 = document.getElementById("state3");

// Button Elements
const btn1On = document.getElementById('btn1On');
const btn1Off = document.getElementById('btn1Off');
const btn2On = document.getElementById('btn2On');
const btn2Off = document.getElementById('btn2Off');
const btn3On = document.getElementById('btn3On');
const btn3Off = document.getElementById('btn3Off');

Database Paths and References

Then, we require to produce database paths to where the GPIOs states are conserved:

// Database path for GPIO states
var dbPathOutput1 = 'board1/outputs/digital/12';
var dbPathOutput2 = 'board1/outputs/digital/13';
var dbPathOutput3 = 'board1/outputs/digital/14';

To be able to interact with the data source on those courses, we need to develop database referrals using those courses:

// Database references
var dbRefOutput1 = firebase.database().ref().child(dbPathOutput1);
var dbRefOutput2 = firebase.database().ref().child(dbPathOutput2);
var dbRefOutput3 = firebase.database().ref().child(dbPathOutput3);

sertupUI() Function

Then, we develop the setupUI() function that will certainly take care of the UI accordingly to the state of the user authentication.

In the auth.js file, we called the setupUI() feature with the user argument setupUI( individual) if the user is visited; or the feature without debate setupUI() when the user is logged out.

So, allow’s inspect what takes place when the user is logged in.

if (user) {

We reveal the verification bar (that shows the individual details and also the logout link). To do that, we can establish its display screen design to block. We likewise desire the websites’s main content with the sensing unit readings to be noticeable.

contentElement.style.display = 'block';
authBarElement.style.display ='block';

Finally, we can obtain the visited customer email with user.email and also present it in the userDetailsElement section as adheres to:

userDetailsElement.innerHTML = user.email;

Get GPIO States

The following lines obtain the GPIO states whenever there’s a change in the database and upgrade the matching HTML components with the brand-new values.

//Update states depending on the database value
dbRefOutput1.on('value', snap => {
  if(snap.val()==1) {
    stateElement1.innerText="ON";
  }
  else{
    stateElement1.innerText="OFF";
  }
});
dbRefOutput2.on('value', snap => {
  if(snap.val()==1) {
    stateElement2.innerText="ON";
  }
  else{
    stateElement2.innerText="OFF";
  }
});
dbRefOutput3.on('value', snap => {
  if(snap.val()==1) {
    stateElement3.innerText="ON";
  }
  else{
    stateElement3.innerText="OFF";
  }
});

Button Events

Then, we include events to the buttons to write 1 or 0 to the equivalent database path as necessary to the button that was pressed.

// Update database upon button click
btn1On.onclick = () =>{
  dbRefOutput1.set(1);
}
btn1Off.onclick = () =>{
  dbRefOutput1.set(0);
}

btn2On.onclick = () =>{
  dbRefOutput2.set(1);
}
btn2Off.onclick = () =>{
  dbRefOutput2.set(0);
}

btn3On.onclick = () =>{
  dbRefOutput3.set(1);
}
btn3Off.onclick = () =>{
  dbRefOutput3.set(0);
}

Logged Out UI

The following fragment manages the UI when the user logs out. We desire to conceal the verification bar as well as the major page web content (GPIO states and also corresponding switches) and show the login kind.

} else{
  // toggle UI elements
  loginElement.style.display = 'block';
  authBarElement.style.display ='none';
  contentElement.style.display = 'none';
}

Favicon File

To present a favicon in your web app, you need to move the image you desire to make use of as favicon to the general public folder. The photo needs to be called favicon.png. You can just drag the favicon file from your computer into the public folder in VS Code.

We’re utilizing the complying with icon as a favicon for our web app:

Deploy your App

After conserving the HTML, CSS, and JavaScript files, deploy your app on VS Code by running the adhering to command on the Terminal window.

firebase deploy

The Terminal ought to show something as adheres to:

ESP32 ESP8266 Deploy Firebase Web App

Firebase supplies a free hosting solution to serve your properties and also web applications. You can access your web app from anywhere.

You can utilize the Hosting URL provided to access your internet app from anywhere.

Demonstration

Congratulations! You efficiently released your app. It is currently hosted on a global CDN making use of Firebase hosting. You can access your internet app from anywhere on the Hosting URL provided. In my case, it is https://esp-firebase-demo.web.app.

Firebase Web App Control ESP32 ESP8266 GPIOs from Anywhere with Authentication

The internet application is receptive, and also you can access it using your smartphone, computer, or tablet computer.

Insert the email and password of the authorized user you added in the Firebase Authentication methods. Afterwards, you can access the control panel to manage the ESP32 or ESP8266 GPIOs.

Go to your job’s Firebase console Hosting tab. You can see your app domain names, deploy background, and also you can also curtail to previous versions of your application.

Firebase Web App Deploy History and Domains

Wrapping Up

In this tutorial, you discovered exactly how to produce a Firebase Web App with login/logout authentication to regulate the ESP32 or ESP8266 GPIOs from anywhere. The GPIO states are saved money on the realtime data source and also the ESP is paying attention to any kind of modifications that happen in the data source to upgrade the GPIOs today. You can quickly include even more GPIOs or more boards to this job.

The database is secured utilizing data source rules. Only licensed verified customers can access the web app to regulate the GPIOs.

You can incorporate this task with other and add even more performances to your app.