ESP8266 Firestore getDocument

Hi guys,
It's the first time for me working with Firestore I want to turn the LED light ON and OFF from firestore through the userID so the work in code has been done by createDocument and getDocument, and it works fine, but the issue here the LED light wont turn ON or OFF.
I might be mistaken with my approach, so here is the Serial monitor results and code you can find it below:

Serial Monitor Results:

Get a document... ok
{
  "name": "projects/smart-tank-ea899/databases/(default)/documents/esp/1klR12zX5yN6bG9VbhTEfopEuoC2",
  "fields": {
    "pump": {
      "stringValue": "off"
    }
  },
  "createTime": "2021-12-02T09:53:49.929163Z",
  "updateTime": "2021-12-02T10:27:27.579671Z"
}
Get a document... ok
{
  "name": "projects/smart-tank-ea899/databases/(default)/documents/esp/1klR12zX5yN6bG9VbhTEfopEuoC2",
  "fields": {
    "pump": {
      "stringValue": "on"
    }
  },
  "createTime": "2021-12-02T09:53:49.929163Z",
  "updateTime": "2021-12-02T10:32:16.830375Z"
}

Code:

#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>
#include <addons/TokenHelper.h>

/* 1. Define the WiFi credentials */
#define WIFI_SSID "Abdallah Agha"
#define WIFI_PASSWORD "abdallah123"

/* 2. Define the API Key */
#define API_KEY "AIza**************************"

/* 3. Define the project ID */
#define FIREBASE_PROJECT_ID "s**********************"

/* 4. Define the user Email and password that alreadey registerd or added in your project */
#define USER_EMAIL "a@a.com"
#define USER_PASSWORD "123456"

//Define Firebase Data object
FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

String uid;

String path;

String firebaseStatus = "on";

void setup()
{

    Serial.begin(115200);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting to Wi-Fi");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);

    /* 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 callback function for the long running token generation task */
    config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

    Firebase.begin(&config, &auth);
    
    Firebase.reconnectWiFi(true);
     //----------
    //LED LIGHT
    //-----------
    pinMode(D1, OUTPUT); 

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

void loop()
{      
          //-------------------
            //Create Document
            //-------------------
            FirebaseJson content;

            
            //---------------------
            //PUMP document is here
            //---------------------
            content.set("fields/pump/stringValue", firebaseStatus);
           
            //esp is the collection id, user uid is the document id in collection info.
            path = "esp/"+uid+"";
            
            Serial.print("Create document... ");

            if (Firebase.Firestore.createDocument(&fbdo, FIREBASE_PROJECT_ID, "" /* databaseId can be (default) or empty */, path.c_str(), content.raw()))
                Serial.printf("ok\n%s\n\n", fbdo.payload().c_str());
            else
                Serial.println(fbdo.errorReason());

         //-------------------
         //Get Document
        //--------------------
        path = "esp/"+uid+"pump";
        String mask = "pump";
        
        Serial.print("Get a document... ");
        if (Firebase.Firestore.getDocument(&fbdo, FIREBASE_PROJECT_ID, "", path.c_str(), firebaseStatus)){
            Serial.printf("ok\n%s\n\n", fbdo.payload().c_str());
            
            if(firebaseStatus == "on"){
              digitalWrite(D1, HIGH);
              }
            
            if(firebaseStatus == "off"){
              digitalWrite(D1, LOW);
              }
              
          }
           else{
            Serial.println(fbdo.errorReason());
        } 
        delay(100);
            
    }

For a similar need, instead of Firebase Firestore I would have used the Firebase Realtime Database (RTDB) as the library allows you to define a stream callback function that is executed every time the data changes, without having to continually poll the document.

Check this example for how-to.

For example, I've done this test project with the addition of a web interface (written with vue, but it can be also in plain html/javascript. It does'nt matter).
if you you want, you can quickly test it putting the content of folder "dist" in a webserver.
Could be hosted also in flash memory of a ESP device for example, but for my purposes I've used .github.io host.

Actually i have used it before and it works really fine and fast, but RTDB in terms of dealing with big data at once it's not gonna help, as google firebase team referred to, but in the other hand Firestore can deal with big data.
To be honest i am working with both of them because i might need both in the near future, so i have completed all of the needed tasks for RTDB but for Firestore i still need to solve this 1 issue which is getting data properly and make it turn ON and OFF LED light from firestore.

Understood.

Aniway in your code I think you have to parse the content of fbdo.payload() wich should be a JSON formatted string, but you are looking for the content of String firebaseStatus passed to getDocument()

Exactly, I'm looking to get firebaseStatus which i have put in content.set in the createDocument().
So what would you suggest to do here?

Try with this code. Basically, using the class included in library, once retrieved the document as you defined, a FirebaseJson object is created with the payload string.
Then with the provided method get(), you can retrieve the content as a string.

  //Get Document
  //--------------------
  path = "esp/" + uid ;

  Serial.print("Get a document... ");
  if (Firebase.Firestore.getDocument(&fbdo, FIREBASE_PROJECT_ID, "", path.c_str(), "")) {
    Serial.printf("ok\n%s\n\n", fbdo.payload().c_str());

    // Create a FirebaseJson object and set content with received payload
    FirebaseJson payload;
    payload.setJsonData(fbdo.payload().c_str());

    // Get the data from FirebaseJson object 
    FirebaseJsonData jsonData;
    payload.get(jsonData, "fields/pump/stringValue", true);
    Serial.println(jsonData.stringValue);
    
    if(jsonData.stringValue == "on"){
      digitalWrite(D1, HIGH);
    }
   // etc etc etc 
  }

1 Like

Thank you so much, i really appreciate it. it worked perfectly. :innocent:

For sure if i also want to use integer values i can replace the stringVlaue with integerValue

More or less :sweat_smile:
not integerValue but intValue

/* 
 * The FirebaseJsonData object holds the returned data which can be read from the following properties.
 * jsonData.stringValue - contains the returned string.
 * jsonData.intValue - contains the returned integer value.
 * jsonData.floatValue - contains the returned float value.
 * jsonData.doubleValue - contains the returned double value.
 * jsonData.boolValue - contains the returned boolean value.
 * jsonData.success - used to determine the result of the get operation.
 * jsonData.type - used to determine the type of returned value in string represent 
 * the types of value e.g. string, int, double, boolean, array, object, null and undefined.
*/
1 Like