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

two functions tested appear not to be working:append string and getting specific value #18

Closed usrdes closed 5 years ago

usrdes commented 5 years ago

Hi tried this library and (a) could not append string and (b) could not get specific value of node. see code below. Please let me know what I am missing?

#include "FirebaseESP32.h"
FirebaseData firebaseData;
static int av1 = 0; // add some values into strings
static int av2 = 1;

void init_firebase() {
Firebase.begin("myProject.firebaseio.com", "1234567890_blah_blah___"); // replace with your proj & secret 
Firebase.reconnectWiFi(true);
Firebase.setMaxRetry(firebaseData, 3);
Firebase.setMaxErrorQueue(firebaseData, 30);
}

//Append many data (multiple keys included nest data) to the database at "/test/update"
// call pushmyData in the loop for updating data1 and data2 values
// also try to setString NewData, and try to append to the string
void pushmyData() {
String k1 = "{\"data1\":\"value";
String k2 = "\", \"data2\":{\"_data2\":\"_value";
String ke = "\"}}";
//String updateData = "{\"data1\":\"value\", \"data2\":{\"_data2\":\"_value\"}}";

String updateData = k1+String(av1)+k2+String(av2)+ke;
   av1++;
   av2++;  
   String s= "Kaboom"+String(av2);
   if(av1 == 1 ) { 
      if( Firebase.setString(firebaseData, "/NewData", s) ) {
          Serial.println("Done setString /NewData:"+s);  // should pust "Kaboom2" to node "NewData"
      } else {
          Serial.println(firebaseData.errorReason());
      }
  } else {
      if (Firebase.pushString(firebaseData, "/NewData", s)) { // should add "Kaboom3" to "Kaboom2"
          Serial.println("Done pushString /NewData:"+s);     // Check firebase data base, to see if 
      } else {                                               // The value of NewData is "Kaboom2Kaboom3"
          Serial.println(firebaseData.errorReason());           // does not seem to be working                  
      }
  }

if (Firebase.updateNode(firebaseData, "/", updateData)) {

  //Success, then try to read the payload value

  //Database path that updated
  Serial.println(firebaseData.dataPath());

  //Data type at updated database path
  Serial.println(firebaseData.dataType()); //Should be "json" -- yes it is

  //Print the JSON string payload that returned from server
  Serial.println(firebaseData.jsonData()); //OK, this works

  //Actual sent payload JSON data
  Serial.println(updateData);

} else {
  //Failed, then print out the error detail
  Serial.println(firebaseData.errorReason());
}

}

// call this routine in loop to see values that are read back 
void query_firebase () {
QueryFilter query;
query.orderBy("data1"); // try to get only data1

if (Firebase.getJSON(firebaseData, "/", query)) // gets the complete data base at "/"
{
  //Success, then try to read the JSON payload value 
  USBPrintln(firebaseData.jsonData());   // prints everything, even if there is a ".indexOn": "data1" on-line at firebase
}
else
{
  //Failed to get JSON data at defined database path, print out the error reason
  USBPrintln(firebaseData.errorReason());
}
//Clear all query parameters
query.clear();

}

// call GetSpecificData() in the main loop, and see if you can get specific
// data for node data2, child _data2, with the value

void GetSpecificData() {
  QueryFilter query;
  query.orderBy("data2");
  query.startAt("_data2");
  query.endAt("_data2");
  String k="No News";
    if(Firebase.getString(firebaseData,"/NewData", k) ) {
      Serial.println("Got NewData as: "+k);
    } else {
      Serial.println(firebaseData.errorReason());
    }
    if (Firebase.getJSON(firebaseData, "/", query)) {
    //Success, then read the payload value
    //Make sure payload value returned from server is integer
    //This prevent you to get garbage data
    if (firebaseData.dataType() == "json") {
      Serial.println(firebaseData.jsonData()); 
    }
  } else {
    //Failed, then print out the error detail
    Serial.println(firebaseData.errorReason());
  }
  //Clear all query parameters
 query.clear();
}
mobizt commented 5 years ago

Ok I'm checking it.

mobizt commented 5 years ago

How about your setup() and loop() functions?

mobizt commented 5 years ago

How about your serial print out result?

usrdes commented 5 years ago

Hi Mobizt, (Thank you for your quick response. It is late night here , will check back to this tomorrow.. Best wishes)

I did not include setup() or loop() because they are OK, in my code. I can see that the WiFi is setup and talks to firebase OK. Hope you can copy the above routines in your "basic.ino" and check it out?

Anyway my serial prinout is included below:

Pushing my data to Firebase now 
Done setString /NewData:Kaboom2
/
json
{"data1":"value0","data2":{"_data2":"_value1"}}
{"data1":"value0", "data2":{"_data2":"_value1"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value0","data2":{"_data2":"_value1"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase 
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom3
/
json
{"data1":"value1","data2":{"_data2":"_value2"}}
{"data1":"value1", "data2":{"_data2":"_value2"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value1","data2":{"_data2":"_value2"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom4
/
json
{"data1":"value2","data2":{"_data2":"_value3"}}
{"data1":"value2", "data2":{"_data2":"_value3"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value2","data2":{"_data2":"_value3"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase 
-----------------------------------------------------------------
ushing my data to Firebase now 
Done pushString /NewData:Kaboom5
/
json
{"data1":"value3","data2":{"_data2":"_value4"}}
{"data1":"value3", "data2":{"_data2":"_value4"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value3","data2":{"_data2":"_value4"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom6
/
json
{"data1":"value4","data2":{"_data2":"_value5"}}
{"data1":"value4", "data2":{"_data2":"_value5"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value4","data2":{"_data2":"_value5"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom7
/
json
{"data1":"value5","data2":{"_data2":"_value6"}}
{"data1":"value5", "data2":{"_data2":"_value6"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value5","data2":{"_data2":"_value6"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom8
/
json
{"data1":"value6","data2":{"_data2":"_value7"}}
{"data1":"value6", "data2":{"_data2":"_value7"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value6","data2":{"_data2":"_value7"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase 
-----------------------------------------------------------------
Pushing my data to Firebase now 
Done pushString /NewData:Kaboom11
/
json
{"data1":"value9","data2":{"_data2":"_value10"}}
{"data1":"value9", "data2":{"_data2":"_value10"}}
Done Pushing my data to Firebase 
Querying Firebase now 
{"NewData":"Kaboom2","data1":"value9","data2":{"_data2":"_value10"}}
Done Querying Firebase 
Querying specific data from Firebase now 
Got NewData as: Kaboom2
{}
Done Querying specific data from  Firebase 
mobizt commented 5 years ago

What is error and please post your working sketch and your database structure. From my testing, I don't see the error from your code you provides.

usrdes commented 5 years ago

I will post full sketch tomorrow, however, in the listing above the first error is as follows:

  1. every time in the loop, the word Kaboom# (where # is 2,3,4,...) is supposed to append to NewData node. For example : Iteration 1 in the loop: NewData: Kaboom2, Iteration 2 in the loop: NewData: Kaboom2Kaboom3 Iteration 3 in the loop: NewData: Kaboom2Kaboom3Kaboom4 ... So if you look in the serialprint above, only the first "Kaboom2" is printed as "Got NewData as: Kaboom2". This means that the NewData did not get appended. I also verified this by looking at my database on firebase

  2. when I look for data2:_data2, I expect to see the value as "_value#" as the new value. However when the serialprint prints out what ever it read back , I see only the following: "Querying specific data from Firebase now Got NewData as: Kaboom2 {}" So I am not sure if I am using the query filter correctly or if I have an incorrect understanding of filters or the data structure etc.

mobizt commented 5 years ago

First

You declare string obj s here


 av2++;  
 String s= "Kaboom"+String(av2);

And use it here 1st time

if( Firebase.setString(firebaseData, "/NewData", s) ) {
   Serial.println("Done setString /NewData:"+s);  // should pust "Kaboom2" to node "NewData"
} else {
   Serial.println(firebaseData.errorReason());
}

1st time db

first

The 2nd time and later use here

if (Firebase.pushString(firebaseData, "/NewData", s)) { // should add "Kaboom3" to "Kaboom2"
   Serial.println("Done pushString /NewData:"+s);     // Check firebase data base, to see if 
 } else {                                               // The value of NewData is "Kaboom2Kaboom3"
   Serial.println(firebaseData.errorReason());          // does not seem to be working                  
 }

The 2nd time result. second

The 3rd and others results

third

then

Go back to where you declare s


 av2++;  
 String s= "Kaboom"+String(av2);

And where you push it.

Firebase.pushString(firebaseData, "/NewData", s)

You will always get Kaboom# instead of Kaboom2Kaboom3Kaboom4Kaboom5....


Second

Again you will see the above image what's happen to data1 and data2 nodes.

then

Below is your code from functions query_firebase() and GetSpecificData() that you try to filter the data in the root node of your db or "/"

if (Firebase.getJSON(firebaseData, "/", query)) // gets the complete data base at "/"

or

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

Which only one .indexOn can be apply to specific node ("/" for this case).

Your query provided two different indexes data1 i.e. query.orderBy("data1"); in query_firebase() and data2 i.e. query.orderBy("data2"); in GetSpecificData() which causes the error when make a Firebase API call to server, the error that returns directly from Firebase server will look like the folowing.

bad request, Index not defined, add \".indexOn\": \"data1\", for path \"/\", to the rules or bad request, Index not defined, add \".indexOn\": \"data2\", for path \"/\", to the rules

Your database rules should be set one of these

{
    "rules": {
        ".read": false,
        ".write": false,
        ".indexOn": "data1"
    }
}

Or

{
    "rules": {
        ".read": false,
        ".write": false,
        ".indexOn": "data2"
    }
}

When you read the data at the root node path which is the parent of all your data, no need to use query to filter unless you are reading the value of dynamic node that created under the known parent key.

If you want to filter the value under "/AAA/AAAA/AAAAA" You may need to set database rules like this.

{
    "rules": {
        ".read": false,
        ".write": false,
        "AAA": {
            "AAAA": {
                ".indexOn": "AAAAA"
            }
        }
    }
}

Wild card also works

{
    "rules": {
        ".read": false,
        ".write": false,
        "AAA": {
            "$ANY": {
                ".indexOn": "AAAAA"
            }
        }
    }
}

I recommend to update the library to version 3.0.2.