ESP32/ESP8266 Firebase: Send BME280 Sensor Readings to the Realtime Database

In this guide, you’ll learn how to send BME280 sensor readings to the Firebase Realtime Database using the ESP32 or ESP8266 NodeMCU boards. The ESP board will authenticate as a user with email and password, and you’ll add database security rules to secure your data. The boards will be programmed using the Arduino core.

ESP32 ESP8266 NodeMCU Firebase Send BME280 Sensor Readings to the Realtime Database

Here’s Part 2 of this project: ESP32/ESP8266: Firebase Web App to Display Sensor Readings (with Authentication)

Other Firebase Tutorials with the ESP32/ESP8266 that you might be interested in:

What is Firebase?

Firebase logo

Firebase is Google’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 authentication, realtime database, hosting, etc.

Project Overview

The following diagram shows a high-level overview of the project we’ll build.

Firebase ESP32 ESP8266 NodeMCU Project Overview
  1. The ESP32/ESP8266 authenticates as a user with email and password (that user must be set on the Firebase authentication methods);
  2. After authentication, the ESP gets the user UID;
  3. The database is protected with security rules. The user can only access the database nodes under the node with its user UID. After getting the user UID, the ESP can publish data to the database;
  4. The ESP sends temperature, humidity and pressure to the database.

These are the main steps to complete this project:

  1. Create Firebase Project
  2. Set Authentication Methods
  3. Get Project API Key
  4. Set up Realtime Database
  5. Set up Database Security Rules
  6. ESP32/ESP8266 Send Sensor Readings to the Realtime Database

You can continue with the Firebase project from this previous tutorial or create a new project. If you use the Firebase project of that previous tutorial, you can skip to section 4) Set up Realtime Database because the authentication methods are already set up.

Preparing Arduino IDE

For this tutorial, we’ll program the ESP32 and ESP8266 boards using the Arduino core. So, make sure you have the ESP32 or ESP8266 add-on installed in your Arduino IDE:

If you want to program the ESP boards using VS Code with the PlatformIO extension, follow the following tutorial instead:

1) Create Firebase Project

1) Go to Firebase and sign in using a Google Account.

2) Click Get Started and then Add project to create a new project.

3) Give a name to your project, for example ESP Firebase Demo.

Create Firebase Project name

4) Disable the option Enable Google Analytics for this project as it is not needed and click Create project.

Set Up Firebase Project for ESP32 and ESP8266 Step 2

5) It will take a few seconds to set up your project. Then, click Continue when it’s ready.

6) You’ll be redirected to your Project console page.

2) Set Authentication Methods

To allow authentication with email and password, first, you need to set authentication methods for your app.

“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 or ESP8266). Knowing a user’s identity allows an app to securely save user data in the cloud and provide the same personalized experience across all of the user’s devices.” To learn more about the authentication methods, you can read the documentation.

1) On the left sidebar, click on Authentication and then on Get started.

Firebase Project Authentication

2) Select the Option Email/Password.

Selecting Firebase Authentication with Email/Password

3) Enable that authentication method and click Save.

Enable Email/password authentication Firebase

4) The authentication with email and password should now be enabled.

Firebase Authentication with Email/Password enabled

5) Now, you need to add a user. On the Authentication tab, select the Users tab at the top. Then, click on Add User.

Firebase Authentication Add New User

6) Add an email address for the authorized user. It can be your google account email or any other email. You can also create an email for this specific project. Add a password that will allow you to sign in to your app and access the database. Don’t forget to save the password in a safe place because you’ll need it later. When you’re done, click Add user.

Firebase Authentication Add User with Email and Password

7) A new user was successfully created and added to the Users table.

Firebase Users Table

Notice that Firebase creates a unique UID for each registered user. The user UID allows us to identify the user and keep track of the user to provide or deny access to the project or the database. There’s also a column that registers the date of the last sign-in. At the moment, it is empty because we haven’t signed in with that user yet.

3) Get Project API Key

To interface with your Firebase project using the ESP32 or ESP8266 boards, you need to get your project API key. Follow the next steps to get your project API key.

1) On the left sidebar, click on Project Settings.

Firebase Project Settings

2) Copy the Web API Key to a safe place because you’ll need it later.

Firebase Project Settings Web API Key

4) Set up Realtime Database

Now, let’s create a realtime database and set up database rules for our project.

1) On the left sidebar, click on Realtime Database and then click on Create Database.

Firebase Project Create Realtime Database

2) Select your database location. It should be the closest to your location.

Set up realtime database firebase ESP32 ESP8266 Select Location

3) Set up security rules for your database. You can select Start in test mode. We’ll change the database rules in just a moment.

Set up realtime database firebase ESP32 ESP8266 Set Security Rules

4) Your database is now created. You need to copy and save the database URL—highlighted in the following image—because you’ll need it later in your ESP32/ESP8266 code.

Firebase Project Database URL

5) Set up Database Security Rules

Now, let’s set up the database rules. On the Realtime Database tab, select the Rules tab at the top. Then, click on Edit rules, copy the following rules and then click Publish.

// 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"
      }
    }
  }
}
Realtime Database creating rules

These rules grant access to a node matching the authenticated user’s UID. This grants that each authenticated user can only access its own data. This means the user can only access the nodes that are under a node with its corresponding user UID. If there are other data published on the database, not under a node with the users’ UID, that user can’t access that data.

For example, imagine our user UID is RjO3taAzMMXBB2Xmir2LQ. With our security rules, it can read and write data to the database under the node UsersData/RjO3taAzMMXBB2Xmir2LQ.

You’ll better understand how this works when you start working with the ESP32/ESP8266.

6) ESP32/ESP8266 Send Sensor Readings to the Realtime Database

In this section, we’ll program the ESP32 or ESP8266 boards to do the following tasks:

  1. Authenticate as a user with email and password (the user you set up in this section);
  2. Send sensor readings to the realtime database as an authorized user.

Parts Required

For this project, you need the following parts*:

* you can also test the project with random values instead of sensor readings, or you can use any other sensor you’re familiar with.

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic Diagram

In this tutorial, we’ll send BME280 sensor readings to the Firebase Realtime Database. So, you need to wire the BME280 sensor to your board. Follow one of the following schematic diagrams.

ESP32 with BME280

We’re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the default ESP32 SCL (GPIO 22) and SDA (GPIO 21) pins, as shown in the following schematic diagram.

ESP32 BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit

Not familiar with the BME280 with the ESP32? Read this tutorial: ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity).

ESP8266 with BME280

We’re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the ESP8266 SDA (GPIO 4) and SCL (GPIO 5) pins, as shown in the following schematic diagram.

ESP8266 NodeMCU BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit

Not familiar with the BME280 with the ESP8266? Read this tutorial: ESP8266 with BME280 using Arduino IDE (Pressure, Temperature, Humidity).

Installing Libraries

For this project, you need to install the following libraries:

Installing Libraries – VS Code

Follow the next instructions if you’re using VS Code with the PlatformIO extension.

Install the Firebase-ESP-Client Library

There is a library with lots of examples to use Firebase with the ESP32: the Firebase-ESP-Client library. This library is compatible with both the ESP32 and ESP8266 boards.

Click on the PIO Home icon and select the Libraries tab. Search for “Firebase ESP Client“. Select the Firebase Arduino Client Library for ESP8266 and ESP32.

Install Firebase ESP Client Library VS Code

Then, click Add to Project and select the project you’re working on.

Add Firebase ESP Client Library to Project VS Code

Install the BME280 Library

In the Libraries tab, search for BME280. Select the Adafruit BME280 library.

PlatformIO VS Code Search for BME280 Library

Then, click Add to Project and select the project you’re working on.

PlatformIO with VS Code Add Library to Project

Also, change the monitor speed to 115200 by adding the following line to the platformio.ini file of your project:

monitor_speed = 115200

Installation – Arduino IDE

Follow this section if you’re using Arduino IDE.

You need to install the following libraries:

Go to Sketch > Include Library > Manage Libraries, search for the libraries’ names and install the libraries.

For the Firebase Client library, select the Firebase Arduino Client Library for ESP8266 and ESP32.

Install Firebase Arduino Client Library for ESP8266 and ESP32 by Mobitz

Now, you’re all set to start programming the ESP32 and ESP8266 boards to interact with the database.

Send Sensor Readings to the Realtime Database Code

Copy the following code to your Arduino IDE or to the main.cpp file if you’re using VS Code.

You need to insert your network credentials, project API key, database URL, and the authorized user email and password.

/*
  Rui Santos
  Complete project details at our blog: https://RandomNerdTutorials.com/esp32-esp8266-firebase-bme280-rtdb/
  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.
*/

#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;

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

// 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;

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

View raw code

How the Code Works

Continue reading to learn how the code works or skip to the demonstration section.

Include Libraries

First, include the required libraries. The WiFi.h library to connect the ESP32 to the internet (or the ESP8266WiFi.h library for the ESP8266 board), the Firebase_ESP_Client.h  library to interface the boards with Firebase, and the Wire, Adafruit_Sensor, and Adafruit_BME280 to interface with the BME280 sensor.

#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>

You also need to include the following for the Firebase library to work.

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

Network Credentials

Include your network credentials in the following lines so that your boards can connect to the internet using your local network.

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

Firebase Project API Key, Firebase User, and Database URL

Insert your Firebase project API key—the one you’ve gotten in this section.

#define API_KEY "REPLACE_WITH_YOUR_PROJECT_API_KEY"

Insert the authorized email and the corresponding password—these are the details of the user you’ve added in this section.

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

Insert your database URL in the following line:

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

Firebase Objects and Other Variables

The following line defines a FirebaseData object.

FirebaseData fbdo;

The next line defines a FirebaseAuth object needed for authentication.

FirebaseAuth auth;

Finally, the following line defines a FirebaseConfig object required for configuration data.

FirebaseConfig config;

The uid variable will be used to save the user’s UID. We can get the user’s UID after the authentication.

String uid;

The following variables will be used to save the nodes to where we’ll send the sensor readings. We’ll update these variables later in the code when we get the user UID.

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

Then, create an Adafruit_BME280 object called bme. This automatically creates a sensor object on the ESP32 or ESP8266 default I2C pins.

Adafruit_BME280 bme; // I2C

The following variables will hold the temperature, humidity, and pressure readings from the sensor.

float temperature;
float humidity;
float pressure;

Delay Time

The sendDataPrevMillis and timerDelay variables are used to check the delay time between each send. In this example, we’re setting the delay time to 3 minutes (18000 milliseconds). Once you test this project and check that everything is working as expected, we recommend increasing the delay.

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

initBME()

The initBME() function initializes the BME280 library using the bme object created previously. Then, you should call this library in the setup().

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

initWiFi()

The initWiFi() function connects your ESP to the internet using the network credentials provided. You must call this function later in the setup() to initialize WiFi.

// 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();
}

Send Data to the Database

To store data at a specific node in the Firebase Realtime Database, you can use the following functions: set, setInt, setFloat, setDouble, setString, setJSON, setArray, setBlob, and setFile.

These functions return a boolean value indicating the success of the operation, which will be true if all of the following conditions are met:

  • The server returns HTTP status code 200
  • The data types matched between request and response

Only setBlob and setFile functions that make a silent request to Firebase server, thus no payload response returned.

Learn more: ESP32: Getting Started with Firebase (Realtime Database)

In our example, we’ll send float variables, so we need to use the setFloat() function as follows.

Firebase.RTDB.setFloat(&fbdo, "DATABASE_NODE", VALUE)

The second argument refers to the database node (char variable) to which we want to send the data. The third argument is the data we want to send (float variable).

As we’ll need to send three float values, we created a function—the sendFloat() function that accepts the node path and the value as arguments.

// 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());
  }
}

Later, we’ll call that function in the loop() to send sensor readings.

setup()

In setup(), initialize the Serial Monitor for debugging purposes at a baud rate of 115200.

Serial.begin(115200);

Call the initBME() function to initialize the BME280 sensor.

initBME();

Call the initWiFi() function to initialize WiFi.

initWiFi();

Assign the API key to the Firebase configuration.

config.api_key = API_KEY;

The following lines assign the email and password to the Firebase authentication object.

auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;

Assign the database URL to the Firebase configuration object.

config.database_url = DATABASE_URL;

Add the following to the configuration object.

// 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 Firebase library (authenticate) with the configuration and authentication settings we defined earlier.

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

After initializing the library, we can get the user UID by calling auth.token.uid. Getting the user’s UID might take some time, so we add a while loop that waits until we get it.

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

Finally, we save the user’s UID in the uid variable and print it in the Serial Monitor.

uid = auth.token.uid.c_str();
Serial.print("User UID: ");
Serial.print(uid);

After getting the user UID, we can update the database node paths to include the user UID. That’s what we do in the following lines.

// 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

loop()

In the loop(), check if it is time to send new readings:

if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)){
  sendDataPrevMillis = millis();

If it is, get the latest sensor readings from the BME280 sensor and save them on the temperature, humidity, and pressure variables.

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

Finally, call the sendFloat() function to send the new readings to the database. Pass as arguments the node path and the value.

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

Demonstration

Upload the previous code to your board. The code is compatible with both the ESP32 and ESP8266 boards. Don’t forget to insert your network credentials, project API key, database URL, user email, and the corresponding password.

After uploading the code, press the board RST button so that it starts running the code. It should authenticate to Firebase, get the user UID, and immediately send new readings to the database.

Open the Serial Monitor at a baud rate of 115200 and check that everything is working as expected.

Arduino IDE Serial Monitor Demonstration

Aditionally, go to the Realtime Database on your Firebase project interface and check that new readings are saved. Notice that it saves the data under a node with the own user UID—this is a way to restrict access to the database.

Arduino IDE Serial Monitor Demonstration

And that’s it. You’ve successfully sent sensor readings to the Firebase Realtime Database, and you protected the data using database rules.

Wrapping Up

In this tutorial, you’ve learned how to authenticate the ESP32/ESP8266 as a user with email and password, send sensor readings to the database, and set up security rules to protect your database and restrict access.

In PART 2, we’ll create a Firebase Web App with authentication (login with email and password) that displays the sensor readings saved on the database. Only an authorized logged-in user can access the data. Later you’ll be able to modify that project to display all sorts of data and restrict or allow access to the data to specific users.

We hope you’ve found this tutorial useful.

>> Continue to Part 2: ESP32/ESP8266: Firebase Web App to Display Sensor Readings (with Authentication)

If you like Firebase projects, please take a look at our new eBook. We’re sure you’ll like it:

Learn more about the ESP32 and ESP8266 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

40 thoughts on “ESP32/ESP8266 Firebase: Send BME280 Sensor Readings to the Realtime Database”

  1. Can I connect MQTT cloud(test.mosquitto.org) to realtime database in firebase? I tried to do so through node-red but it didn’t work.

    Reply
  2. How to set firebase authentication dynamicly through web server or mobile app and save in memory of esp32 (EPROM) so no hard coded auth will need and easy for iot devices development

    Reply
    • Hi.
      you would need to create an access point with the ESP32 that would load a form where you would enter the user email and password.
      Then, those credentials would be written permanently on the ESP32 memory (like SPIFFS, for example).
      Then, to initialize Firebase, you would need to read from SPIFFS to get email and password.
      You can implement something like this “Wi-Fi Manager” we implemented on the following project. But instead of SSID and password, you would insert email and password:
      https://randomnerdtutorials.com/esp32-status-indicator-sensor-pcb/
      Regards,
      Sara

      Reply
  3. Perfect tuturial but my program stands on “Getting User UID” following many dots.
    Where have I tu put User UID in the sketch?
    Thanks
    Renzo

    Reply
  4. Hi Sara,

    Great tutorial!
    It looks the sensor readings are updated every 3 minutes in the firebase database.
    Is the data also logged over time in the database?
    So that you log the temperature over several weeks for example and export a tab delimited text file with all the sensor readings?

    Best, Rob

    Reply
    • Hi.
      In this specific project no.
      It overwrites the current values.
      I’m already preparing a new tutorial that logs the data over time with timestamps.
      So, you’ll have historical data saved.
      Regards,
      Sara

      Reply
  5. Dear Sara, I bought your books, thanks a lot.
    Two simple questions:
    1- Should be possible to connect to RTDB more than one device (board) ? I think so.
    2- Can the different boards exchange data ?
    Thanks.

    Reply
    • Hi.
      Yes. More than one board can connect to the database. Each board can be an independent user or be configured to be the same user.
      Yes. The boards can exchange data because you can read and write to the database with both boards, and you can give permissions so that all boards access all data.
      Regards,
      Sara

      Reply
  6. Dear Sara,

    Hi ! Great tutorial !

    I’ve tried run the code on Arduino IDE but doesn’t work and show a message about wrong compilating for AI Thinker ESP32-CAM.

    Why this happened ? Can I solve it ?

    Best Regards,

    Lucas

    Reply
      • Hi Sara,

        Thanks for answer.

        Yes, I’m using an ESP32-CAM. The error is exacty the message below.

        Arduino: 1.8.13 (Windows 10), Placa:”AI Thinker ESP32-CAM, 240MHz (WiFi/BT), QIO, 80MHz”

        In file included from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/common.h:41:0,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Utils.h:37,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/signer/Signer.h:37,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase.h:47,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase_ESP_Client.h:50,

        from C:\Users\lucas\Documents\IoT\ESP32 CAM\Pluviógrafo\Firebase\Pluv_fb\Pluv_fb.ino:9:

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:43:1: error: expected class-name before ‘{‘ token

        {

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h: In member function ‘int FB_WCS::_connect(const char*, uint16_t, long unsigned int)’:

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:50:5: error: ‘_timeout’ was not declared in this scope

        _timeout = timeout;

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:52:27: error: ‘connect’ was not declared in this scope

        if (connect(host, port) == 0)

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:54:11: error: ‘_CA_cert’ was not declared in this scope

        if (_CA_cert != NULL)

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:55:32: error: ‘sslclient’ was not declared in this scope

        mbedtls_x509_crt_free(&sslclient->ca_cert);

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:55:50: error: ‘mbedtls_x509_crt_free’ was not declared in this scope

        mbedtls_x509_crt_free(&sslclient->ca_cert);

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/wcs/esp32/FB_TCP_Client.h:58:5: error: ‘_connected’ was not declared in this scope

        _connected = true;

        ^

        In file included from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Utils.h:37:0,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/signer/Signer.h:37,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase.h:47,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase_ESP_Client.h:50,

        from C:\Users\lucas\Documents\IoT\ESP32 CAM\Pluviógrafo\Firebase\Pluv_fb\Pluv_fb.ino:9:

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/common.h: At global scope:

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/common.h:766:5: error: ‘mbedtls_pk_context’ does not name a type

        mbedtls_pk_context *pk_ctx = nullptr;

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/common.h:767:5: error: ‘mbedtls_entropy_context’ does not name a type

        mbedtls_entropy_context *entropy_ctx = nullptr;

        ^

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/common.h:768:5: error: ‘mbedtls_ctr_drbg_context’ does not name a type

        mbedtls_ctr_drbg_context *ctr_drbg_ctx = nullptr;

        ^

        In file included from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase.h:49:0,

        from C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/Firebase_ESP_Client.h:50,

        from C:\Users\lucas\Documents\IoT\ESP32 CAM\Pluviógrafo\Firebase\Pluv_fb\Pluv_fb.ino:9:

        C:\Users\lucas\Documents\Arduino\libraries\Firebase_Arduino_Client_Library_for_ESP8266_and_ESP32\src/session/FB_Session.h:347:3: error: ‘WiFiClientSecure’ does not name a type

        WiFiClientSecure *getWiFiClient();

        ^

        Foram encontradas múltiplas bibliotecas para “SD.h”

        Usado: C:\Users\lucas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SD

        Não usado: C:\Program Files (x86)\Arduino\libraries\SD

        Foram encontradas múltiplas bibliotecas para “WiFi.h”

        Usado: C:\Users\lucas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi

        Não usado: C:\Program Files (x86)\Arduino\libraries\WiFi

        exit status 1

        Erro compilando para a placa AI Thinker ESP32-CAM

        Reply
        • Hi.
          I never tried this library with the ESP32-CAM.
          Did you try the example with a “normal” ESP32 first? Just to check if it is a problem with the library or with the board.
          Regards,
          Sara

          Reply
  7. Hi Sara, thank you for the great tutorial. Unfortunately the ESP32 have some troubles quite often. Can you help me resolve this problem? 🙂
    The serial log is this:

    Token info: type = id token, status = on request
    Token info: type = id token, status = ready
    Getting User UID
    User UID: the user ID
    FAILED
    REASON: connection refused
    Writing value: 25.02 on the following path: /UsersData/the user ID/humidity
    PASSED
    PATH: /UsersData/the user ID/humidity
    TYPE: double
    Writing value: 945.23 on the following path: /UsersData/the user ID/pressure
    PASSED
    PATH: /UsersData/the user ID/pressure
    TYPE: double
    Writing value: 25.97 on the following path: /UsersData/the user ID/temperature
    PASSED
    PATH: /UsersData/the user ID/temperature
    TYPE: float
    Writing value: 24.86 on the following path: /UsersData/the user ID/humidity
    PASSED
    PATH: /UsersData/the user ID/humidity
    TYPE: float
    Writing value: 945.20 on the following path: /UsersData/the user ID/pressure
    PASSED
    PATH: /UsersData/the user ID/pressure
    TYPE: double
    Writing value: 26.19 on the following path: /UsersData/the user ID/temperature
    PASSED
    PATH: /UsersData/the user ID/temperature
    TYPE: float
    FAILED
    REASON: connection refused
    FAILED
    REASON: connection refused
    FAILED
    REASON: connection refused
    FAILED
    REASON: connection refused
    Writing value: 945.23 on the following path: /UsersData/the user ID/pressure
    PASSED
    PATH: /UsersData/the user ID/pressure
    TYPE: double
    Writing value: 26.51 on the following path: /UsersData/the user ID/temperature
    PASSED
    PATH: /UsersData/the user ID/temperature
    TYPE: float
    Writing value: 24.27 on the following path: /UsersData/the user ID/humidity
    PASSED
    PATH: /UsersData/the user ID/humidity
    TYPE: double
    Writing value: 945.27 on the following path: /UsersData/the user ID/pressure
    PASSED
    PATH: /UsersData/the user ID/pressure
    TYPE: double
    FAILED
    REASON: connection refused
    Writing value: 24.26 on the following path: /UsersData/the user ID/humidity
    PASSED
    PATH: /UsersData/the user ID/humidity
    TYPE: double
    FAILED
    REASON: connection refused
    FAILED
    REASON: connection refused
    FAILED
    REASON: connection refused
    [E][ssl_client.cpp:36] _handle_error(): [start_ssl_client():216]: (-29312) SSL – The connection indicated an EOF
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -29312
    FAILED
    REASON: send request failed

    And also sometimes:

    [E][WiFiGeneric.cpp:739] hostByName(): DNS Failed for securetoken.googleapis.com
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    [E][WiFiGeneric.cpp:739] hostByName(): DNS Failed for securetoken.googleapis.com
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    [E][WiFiGeneric.cpp:739] hostByName(): DNS Failed for securetoken.googleapis.com
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    [E][WiFiGeneric.cpp:739] hostByName(): DNS Failed for securetoken.googleapis.com
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    [E][WiFiGeneric.cpp:739] hostByName(): DNS Failed for securetoken.googleapis.com
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    [E][ssl_client.cpp:70] start_ssl_client(): ERROR opening socket
    [E][WiFiClientSecure.cpp:133] connect(): start_ssl_client: -1
    Token info: type = id token, status = error
    Token error: code: -4, message: connection lost
    Token info: type = id token, status = on request
    Guru Meditation Error: Core 1 panic’ed (StoreProhibited). Exception was unhandled.
    Core 1 register dump:
    (…)

    I haven’t done anything with the device or firebase and I haven’t rebooted.

    Have a great day!

    Reply
    • Hi.
      Make sure your board has a good wi-fi connection.
      Did you change anything on the code?
      Try to increase the delay time between each reading sent to the database and check if that solves the problem.
      Regards,
      Sara

      Reply
  8. Hello,
    I would like control my ESP8266 from the database. So, I use
    Firebase.setString(“LED”, “OFF”);
    and then, with Firebase.getString () function, I am trying to control an output.
    But this library has no member named setString or getString.

    Could you please how can I control -let say- a LED on ESP8266 from firebase?

    Reply
    • Hi.
      I already have that project created.
      It will be published at the beginning of next month.
      So, stay tuned.
      Regards,
      Sara

      Reply
  9. Dear Sara,

    Thank you very much for your work. It is allways an inspiration.

    Maybe you can help me to solve a problem I am fiddeling around since a couple of days and that meanwhile gave my nerves the rest.

    Given is a well defined and static Firebase database (see at the end of this text).
    At a random place in my code I want to update the value of a unique key. In this particular case, it is the string value of field time of sensor1 of board1.

    It is assumed that the ESP32-boards do not change the database design. Without time series there is not only no necessity to do that, but furthermore also a common principle that clients must not do that.

    I am using the Firebase_ESP_Client library from Suwatchai (Mobizt).

    Code1:
    #define TSTMP1 “/ESPWK1/board1/sensor1/timestamp”
    Serial.printf(“Set timestamp… %s\n”, Firebase.RTDB.setTimestamp( & fbdo, TSTMP1) ? “ok” : fbdo.errorReason().c_str());
    timestmp1 = fbdo.to < int > () + 7200;

    Works, the value of e.g. 1659712471132 is written to the corresponding timestamp.
    But it will also work, if the initial database would not even contain the node timestamp. So it will create that node. Maybe that could be handled somehow but that does not interest me at the moment.

    Code2:
    #define TIME1 “/ESPWK1/board1/sensor1/time”
    char bufferarray[32] = “”;
    sprintf(bufferarray,”%02d-%02d-%4d-%02d:%02d:%02d\n”, day(timestmp1), month(timestmp1), year(timestmp1), hour(timestmp1), minute(timestmp1), second(timestmp1));
    json.set(“time”, bufferarray);
    Serial.printf(“Set json… %s\n”, Firebase.RTDB.setJSON(&fbdo, TIME1, &json) ? “ok” : fbdo.errorReason().c_str());

    this will create an additional node time under the existing time. It looks like this:
    },
    “sensor1”: {
    “sens1”: -99,
    “sens2”: -99,
    “sens3”: -99,
    “sens4”: -99,
    “sensorname”: “Sensor1”,
    “time”: {
    “time”: “05-08-2022-17:14:31\n”
    },
    “timestamp”: 1659712471132
    },
    “sensor2”: {

    The question is, which code snippet will access a certain defined existing node to put string data in its value field.

    Start of project: Database definition as json object:
    {
    “ESPWK1”: {
    “board1”: {
    “boardname”: “Board1”,
    “outputs”: {
    “digital”: {
    “do1”: 0,
    “do2”: 0,
    “do3”: 0,
    “do4”: 0
    },
    “analog”: {
    “ao1”: 0.000,
    “ao2”: 0.000,
    “ao3”: 0.000,
    “ao4”: 0.000
    },
    “pwm1”: {
    “f”: 0,
    “dc”: 0
    },
    “pwm2”: {
    “f”: 0,
    “dc”: 0
    }
    },
    “inputs”: {
    “digital”: {
    “di1”: 0,
    “di2”: 0,
    “di3”: 0,
    “di4”: 0
    },
    “analog”: {
    “ai1”: 0.000,
    “ai2”: 0.000,
    “ai3”: 0.000,
    “ai4”: 0.000
    }
    },
    “sensor1”: {
    “sensorname”: “Sensor1”,
    “timestamp”: 0,
    “time”: “”,
    “sens1”: -99.000,
    “sens2”: -99.000,
    “sens3”: -99.000,
    “sens4”: -99.000
    },
    “sensor2”: {
    “sensorname”: “Sensor2”,
    “timestamp”: 0,
    “time”: “”,
    “sens1”: -99.000,
    “sens2”: -99.000,
    “sens3”: -99.000,
    “sens4”: -99.000
    },
    “sensor3”: {
    “sensorname”: “Sensor3”,
    “timestamp”: 0,
    “time”: “”,
    “sens1”: -99.000,
    “sens2”: -99.000,
    “sens3”: -99.000,
    “sens4”: -99.000
    }
    },
    “board2”: {
    “boardname”: “Board2”,
    “outputs”: {

    (in total there are 4 boards with identical structure)
    }

    End of database definition.

    Reply
  10. Hello, almost everything is ready. There is an error in the monitor at the end.

    Connecting to WiFi …192.168.116.190
    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
    Getting User UID………
    Can you help?

    Reply
  11. Hello,

    I’m trying to combine this code with the GPIO control code, but it doesn’t work when combining them.

    I set different FirebaseJson for reading and writing and it didn’t work either.

    The reading of the sensors works, but the control of the outputs does not work.

    The terminal shows me:

    stream timeout, resuming…

    do you know what could be the error?

    Thank you very much

    Reply
  12. Dear Sara
    I have followed your tutorial and added the HX711 module to my project. However, I am facing some issues and I would like to save data to the database only when the weight exceeds 100 grams. Can you guide me on how to do this? Thank you.

    Reply
  13. sous PlatforIO, avec visual studio,sur la ligne:
    databasePath = “/UsersData/” + uid; une tile apparait sous le +
    erreur plusieurs opérateurs “+” correspondent à ces opérandes :C/C++(350)
    Comment remedier a cela?

    Merci.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.