En esta guía, se creará una aplicación web en Firebase para mostrar las lecturas de los sensores guardadas en Firebase Realtime Database. La página web de lecturas del sensor está protegida con autenticación por medio de correo electrónico y contraseña.

El siguiente diagrama muestra el proyecto a grandes rasgos que vamos a construir

Lo primero que debemos hacer es ingresar a Firebase Console y crear un nuevo proyecto.

Luego nombramos el proyecto, en mi caso Espyoutube32

Le marcamos continuar en el proceso

Generamos un nombre para la configuracion de Google Analytics, en mi caso puse Esp32Youtube

Luego firebase construye el proyecto con los parametros establecidos

Ingresamos en la opción web

Le indicamos en la opcion de configura Firebase Hosting y le ponemos un nombre, en este caso Sensor App

Nos muestra el siguiente fragmento de codigo, recomiendo guardarlo en un blog de notas, por que lo necesitaremos mas adelante.

Le damos siguientes, siguiente y siguente hasta finalizar.

debemos instalar el Firebase CLI, para continuar con el proceso, el siguiente es el comando:

npm install -g firebase-tools

En mi caso, cree una carperta en el escritorio que se llama FirebaseYoutube y en la terminar ingreso en la carpeta, luego doy al comando para instalar el Firebase CLI, como lo muestra la imagen.

Ahora se ingresa el comando de firebase login

firebase login

Y aparece una ventana del navegador, solicitando ingreso a la cuenta de gmail que se utilizo para el proceso de firebase

Posteriormente saldra el mensaje de que el login a sido exitoso

firebase init

Cuando ingresamos el comando de firebase init, nos muestra la pregunta, a la cual marcamos con una “y” y luego ENTER

Luego aparece la siguiente configuración, con la Barra Espaciadora, seleccionamos las siguientes opciones y luego ENTER

Luego seleccionamos la opcion de Use an existing project.

Aparecera el proyecto que creamos anteriormente

Luego pregunta si la inicializamos, le marcamos con la “y” y posteriormente seleccionamos el us-central1

A esta opcion simplemente presionamos ENTER

A la siguiente opciones le marcamos con “n“, para decirle que no

Las siguientes son las opciones que se dejaron marcadas en los anteriores pasos.

Cuando terminamos el proceso, el crea por defecto los siguientes archivos.

Ahora damos el comando firebase deploy, para que lo despliegue a produccion en el hosting de firebase

firebase deploy

Luego del deploy el genera un link en la consola donde podemos ingresar

Y nos muestra la página por defecto que el crea.

Ahora si, vamos a subir nuestro codigo en la pagina, para darle un poco de logica, latoneria y pintura a nuestro proyecto. Debemos descargar los archivos en el siguiente Github y reemplazamos los archivos de index.html

<!DOCTYPE html>
<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: "",
          projectId: "",
          storageBucket: "",
          messagingSenderId: "",
          appId: "",
          measurementId: ""
      };
      // 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>Read Sensor App <i class="fas fa-clipboard-list"></i></h1>
  </div>
  <!--AUTHENTICATION BAR (USER DETAILS/LOGOUT BUTTON)-->
  <div id="authentication-bar" style="display: none;">
    <p><span id="authentication-status">Usuario Logged</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="cards">
      <!--TEMPERATURE-->
      <div class="card">
        <p><i class="fas fa-thermometer-half" style="color:#e72b3b;"></i> TEMPERATURA</p>
        <p><span class="reading"><span id="temp"></span> °C</span></p>
      </div>
      <!--HUMIDITY-->
      <div class="card">
        <p><i class="fas fa-tint" style="color:#00add6;"></i> HUMEDAD</p>
        <p><span class="reading"><span id="hum"></span> &percnt;</span></p>
      </div>
      <!--PRESSURE-->
      <div class="card">
        <p><i class="fas fa-rocket" style="color:#e47637;"></i> PRESIÓN</p>
        <p><span class="reading"><span id="pres"></span> hPa</span></p>
      </div>
    </div>
  </div>
    <script src="scripts/auth.js"></script>
    <script src="scripts/index.js"></script>
  </body>
</html>

Luego copiamos la carpeta de scripts, dentro de la carpeta

Y luego el archivos de style.css

Y por ultimo la imagen png del favicon

Ahora, recuerdas el fragmento de codigo que les conte que debiamos guardar en un blog de notas que generaba el firebase?, pues aqui debemos reemplazarlo.

Ya que acomodamos los archivos, nuevamente le indicamos el firebase deploy, para subir nuevamente los archivos al hosting.

Si subimos correctamente los archivos, en el link que genera nuevamente, ya nos deberia mostrar la siguiente interfaz.

Ahora el siguiente paso, es crear un usuario y una contraseña en firebase para poder ingresar. Entonces volvemos nuevamente a firebase y le damos en la opción Authentication

Le damos a comenzar y posteriormente mostrara la siguiente imagen, debemos escoger la opcion de correo electronico y contraseña

Le marcamos habilitar

Y luego vamos a la pestaña de Users, para crear nuestro cliente

Y creamos nuestro usuario, con un correo y contraseña

Con esas credenciales ya podemos probar si ingressa a nuestro dashboard

Ahora ya ingresara a la siguiente pantalla

Finalmente debemos generar una ultima configuracion en firebase, para eso vamos a la opcion Realtime Database

Le damos crear una base de datos y se nos muestra el siguiente modal, en el cual seleccionamos la opcion que aparece en la imagen

Vamos a la opcion Reglas, pegamos las reglas que aparece en la imagen y le damos publicar

// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
  "rules": {
    "UsersData": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

Ahora le damos en el engranaje en la parte superior y copiamos la clave de API, ya que la vamos a necesitar para el programa del ESP32

En el programa del ESP32, que ya descargamos cambiamos los datos necesarios que ya hemos creado anteriormente

#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
//#include <Adafruit_BME280.h>

// Provide the token generation process info.
#include "addons/TokenHelper.h"
// Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

// Insert your network credentials
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

// Insert Firebase project API Key
#define API_KEY "REPLACE_WITH_YOUR_PROJECT_API_KEY"

// Insert Authorized Email and Corresponding Password
#define USER_EMAIL "REPLACE_WITH_THE_USER_EMAIL"
#define USER_PASSWORD "REPLACE_WITH_THE_USER_PASSWORD"

// Insert RTDB URLefine the RTDB URL
#define DATABASE_URL "REPLACE_WITH_YOUR_DATABASE_URL"

// Define Firebase objects
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

// Variable to save USER UID
String uid;

// Variables to save database paths
String databasePath;
String tempPath;
String humPath;
String presPath;

// BME280 sensor
//Adafruit_BME280 bme; // I2C
float temperature;
float humidity;
float pressure;
float contador =1.0;

// Timer variables (send new readings every three minutes)
unsigned long sendDataPrevMillis = 0;
unsigned long timerDelay = 5000;

// Initialize BME280
/*void initBME(){
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}*/

// Initialize WiFi
void initWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
  Serial.println();
}

// Write float values to the database
void sendFloat(String path, float value){
  if (Firebase.RTDB.setFloat(&fbdo, path.c_str(), value)){
    Serial.print("Writing value: ");
    Serial.print (value);
    Serial.print(" on the following path: ");
    Serial.println(path);
    Serial.println("PASSED");
    Serial.println("PATH: " + fbdo.dataPath());
    Serial.println("TYPE: " + fbdo.dataType());
  }
  else {
    Serial.println("FAILED");
    Serial.println("REASON: " + fbdo.errorReason());
  }
}

void setup(){
  Serial.begin(115200);

  // Initialize BME280 sensor
  //initBME();
  initWiFi();

  // Assign the api key (required)
  config.api_key = API_KEY;

  // Assign the user sign in credentials
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  // Assign the RTDB URL (required)
  config.database_url = DATABASE_URL;

  Firebase.reconnectWiFi(true);
  fbdo.setResponseSize(4096);

  // Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  // Assign the maximum retry of token generation
  config.max_token_generation_retry = 5;

  // Initialize the library with the Firebase authen and config
  Firebase.begin(&config, &auth);

  // Getting the user UID might take a few seconds
  Serial.println("Getting User UID");
  while ((auth.token.uid) == "") {
    Serial.print('.');
    delay(1000);
  }
  // Print user UID
  uid = auth.token.uid.c_str();
  Serial.print("User UID: ");
  Serial.println(uid);

  // Update database path
  databasePath = "/UsersData/" + uid;

  // Update database path for sensor readings
  tempPath = databasePath + "/temperature"; // --> UsersData/<user_uid>/temperature
  humPath = databasePath + "/humidity"; // --> UsersData/<user_uid>/humidity
  presPath = databasePath + "/pressure"; // --> UsersData/<user_uid>/pressure
}

void loop(){
  // Send new readings to database
  if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)){
    sendDataPrevMillis = millis();
    

    // Get latest sensor readings
   /* temperature = bme.readTemperature();
    humidity = bme.readHumidity();
    pressure = bme.readPressure()/100.0F;*/

    ///////COMENTAN ESTA SECCION SI DESEAN UTILIZAR EL BME////////////////
      if(contador>20){contador = 1.0;}
      contador=contador+1;
    temperature = contador*0.1;
    humidity = contador*0.2;
    pressure = contador*0.3;


    // Send readings to database:
    sendFloat(tempPath, temperature);
    sendFloat(humPath, humidity);
    sendFloat(presPath, pressure);
  }
}

Para la DATABASE_URL, debemos ingresar a la siguiente opcion y copiar la url que nos muestra en la imagen.

Finalmente le damos programar al ESP32 y deberia generar el envio de datos desde la placa a firebase, y poder ver los datos desde la página web

Gracias por leernos, espero les ayude 🙂