mobizt / Firebase-ESP32

[DEPRECATED]🔥 Firebase RTDB Arduino Library for ESP32. The complete, fast, secured and reliable Firebase Arduino client library that supports CRUD (create, read, update, delete) and Stream operations.
MIT License
415 stars 118 forks source link

HELP needed on the database size management #121

Closed Sixonlon closed 3 years ago

Sixonlon commented 3 years ago

Hi there,

Thanks for your library, very usefull. I'm currently building a web server that read the data stored in a firebase database but I would like to manage it in that way : I want to limit the max number of data (actually I upload JSON data) stored to a certain number. When I need to upload new data, I would like the oldest one to be deleted and then add the new one. I had the idea to add in my JSON object the firebase timestamp and then querry my datas by using the timestamp. I would store the information and then use it to delete the oldest node before uploading a new one.

I manage to upload my data with the timestamp but I'm stuck on the querry part. the way I structure my database is as followed : -key XXXXXXXXXX data : the actual data (an Integer) timestamp : the timestamp -key YYYYYYYYYY data : the actual data (an Integer) timestamp : the timestamp -key ZZZZZZZZZZ data : the actual data (an Integer) timestamp : the timestamp ....

Here is the code I use. What do I do wrong with the querry part ? Would there exist another way to do what I want ? I tough of generate a custom key instead of the random one generated automatically that name would be stored. I would then track the X latest name added and then delete the oldest one when I upload new data. But keeping track of that would be quite heavy in think.

Thanks in advance ;)

#include <Arduino.h>
#include <WiFi.h>
#include <FirebaseESP32.h>

#define FIREBASE_HOST "XXXXXXXXb.firebaseio.com"
#define FIREBASE_AUTH "SECRET"
#define WIFI_SSID "WIFI_SSID "
#define WIFI_PASSWORD "WIFI_PASSWORD "

byte rxindex = 0;
char rxdata[32];

//Define Firebase Data object
FirebaseData firebaseData;

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

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

  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);
}
void printResult(FirebaseData &data)
{
    if (data.dataType() == "int")
        Serial.println(data.intData());
    else if (data.dataType() == "float")
        Serial.println(data.floatData(), 5);
    else if (data.dataType() == "double")
        printf("%.9lf\n", data.doubleData());
    else if (data.dataType() == "boolean")
        Serial.println(data.boolData() == 1 ? "true" : "false");
    else if (data.dataType() == "string")
        Serial.println(data.stringData());
    else if (data.dataType() == "json")
    {
        Serial.println();
        FirebaseJson &json = data.jsonObject();
        //Print all object data
        Serial.println("Pretty printed JSON data:");
        String jsonStr;
        json.toString(jsonStr,true);
        Serial.println(jsonStr);
        Serial.println();
        Serial.println("Iterate JSON data:");
        Serial.println();
        size_t len = json.iteratorBegin();
        String key, value = "";
        int type = 0;
        for (size_t i = 0; i < len; i++)
        {
            json.iteratorGet(i, type, key, value);
            Serial.print(i);
            Serial.print(", ");
            Serial.print("Type: ");
            Serial.print(type == FirebaseJson::JSON_OBJECT ? "object" : "array");
            if (type == FirebaseJson::JSON_OBJECT)
            {
                Serial.print(", Key: ");
                Serial.print(key);
            }
            Serial.print(", Value: ");
            Serial.println(value);
        }
        json.iteratorEnd();
    }
    else if (data.dataType() == "array")
    {
        Serial.println();
        //get the array data from FirebaseData using FirebaseJsonArray object
        FirebaseJsonArray &arr = data.jsonArray();
        //Print all array values
        Serial.println("Pretty printed Array:");
        String arrStr;
        arr.toString(arrStr,true);
        Serial.println(arrStr);
        Serial.println();
        Serial.println("Iterate array values:");
        Serial.println();
        for (size_t i = 0; i < arr.size(); i++)
        {
            Serial.print(i);
            Serial.print(", Value: ");

            FirebaseJsonData &jsonData = data.jsonData();
            //Get the result data from FirebaseJsonArray object
            arr.get(jsonData, i);
            if (jsonData.typeNum == FirebaseJson::JSON_BOOL)
                Serial.println(jsonData.boolValue ? "true" : "false");
            else if (jsonData.typeNum == FirebaseJson::JSON_INT)
                Serial.println(jsonData.intValue);
            else if (jsonData.typeNum == FirebaseJson::JSON_FLOAT)
              Serial.println(jsonData.floatValue);
            else if (jsonData.typeNum == FirebaseJson::JSON_DOUBLE)
                printf("%.9lf\n", jsonData.doubleValue);
            else if (jsonData.typeNum == FirebaseJson::JSON_STRING ||
                     jsonData.typeNum == FirebaseJson::JSON_NULL ||
                     jsonData.typeNum == FirebaseJson::JSON_OBJECT ||
                     jsonData.typeNum == FirebaseJson::JSON_ARRAY)
                Serial.println(jsonData.stringValue);
        }
    }
    else
    {
      Serial.println(data.payload());
    }
}

void Querrying(){
  QueryFilter query;

  query.orderBy("Timestamp");
  query.startAt(0);
  query.endAt(firebaseData.doubleData());
  query.limitToLast(8);

  //Begin the data filtering test
  Serial.println("------------------------------------");
  Serial.println("Data Filtering test...");

  if (Firebase.getJSON(firebaseData, "/Volume", query))
  {

    Serial.println("PASSED");
    Serial.println("JSON DATA: ");
    printResult(firebaseData);
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }

  //Clear all query parameters
  query.clear();

}

void process_command(char *command){
  String path = "/Test";
  FirebaseJson Package;

  char *cmd;
  cmd = strtok(command, " \r");

  // Bit of code adding data to Databese (called here firebaseData) and the server timestamp
  if (strcmp(cmd, "11") == 0){
    String access;
    cmd = strtok(NULL, " \r");
    Serial.println("------------------------------------");
    Serial.println(" ## Add new data");
    Package.clear();
    Package.add("Donnee",11);
    Package.add("Timestamp");
    if(Firebase.pushJSON(firebaseData, "/Volume", Package)){
      Serial.print("Node added : ");
      access = firebaseData.pushName();
      Serial.println(access);
    }
    else{
      Serial.println(firebaseData.errorReason());
    }

    Serial.println(" ## Set Timestamp test...");
    if (Firebase.pushTimestamp(firebaseData, "Volume/"+access+"/Timestamp"))
    {
      Serial.println("PASSED");
      Serial.println("PATH: " + firebaseData.dataPath());
      Serial.println("------------------------------------");
      Serial.println();
    }
    else
    {
      Serial.println("FAILED");
      Serial.println("REASON: " + firebaseData.errorReason());
      Serial.println("------------------------------------");
      Serial.println();
    }
  } else 
  if (strcmp(cmd, "12") == 0){
    String access;
    cmd = strtok(NULL, " \r");
    Serial.println("------------------------------------");
    Serial.println(" ## Add new data");
    Package.clear();
    Package.add("Donnee",12);
    Package.add("Timestamp");
    if(Firebase.pushJSON(firebaseData, "/Volume", Package)){
      Serial.print("Node added : ");
      access = firebaseData.pushName();
      Serial.println(access);
    }
    else{
      Serial.println(firebaseData.errorReason());
    }

    Serial.println(" ## Set Timestamp test...");
    if (Firebase.pushTimestamp(firebaseData, "Volume/"+access+"/Timestamp"))
    {
      Serial.println("PASSED");
      Serial.println("PATH: " + firebaseData.dataPath());
      Serial.println("------------------------------------");
      Serial.println();
    }
    else
    {
      Serial.println("FAILED");
      Serial.println("REASON: " + firebaseData.errorReason());
      Serial.println("------------------------------------");
      Serial.println();
    }
  }else 
  if(strcmp(cmd,"querry")==0){
    Serial.println("--------------------------");
    Serial.println("Querying begins");
    Querrying();

  }
  {
    Serial.print(F("Unknown command\n"));
  }
}

void loop()
{
  // Handle the serial in
  if(Serial.available()>0)
  {
    rxdata[rxindex]= Serial.read();
     if (rxdata[rxindex] == '\r'){ //return
      Serial.print(F("\n"));
      rxdata[rxindex] = '\0';

      process_command(rxdata);
      rxindex = 0;
    } else if (rxdata[rxindex] == '\b')
    { //backspace
      if (rxindex > 0)
      {
        Serial.print(F("\b \b"));
        rxindex--;
      }
    }
    else  //other char
    {
      Serial.print(rxdata[rxindex]);
      rxindex++;
      if (rxindex >= 32)
      {
        rxindex = 0;
      }
    }
  }
  // put the rest of the code here
}
mobizt commented 3 years ago

You need to set the .indexOn in the database rules to the parent node with the name of child node to be queried.

Please see this example.

Sixonlon commented 3 years ago

Thks man!