0

I have a mobile app (done using MIT App Inventor) storing some values to a Firebase database. App inventor stores all the values as strings (i.e. with quotes, and strings have quotes enclosed within quotes eg. "\"hello\"").

I'm using this library to fetch data from Firebase to ESP8266. I'm using String var to store the value retrieved and then change it to a CString (trying to store it directly doesn't work) as below:

This doesn't work:

Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/FREQ FR");
Serial.print("node -- schedule1 /FREQ FR -- type: ");   
Serial.println(firebaseData.dataType());
char * cstr1 = new char [33];
cstr1 = firebaseData.stringData(); 
Serial.print(" -- data: ");
Serial.println(cstr1);  

This works:

Firebase.get(firebaseData, "/SCHEDULE DETAILS/SCHEDULE1/WEIGHT");
Serial.print("node -- schedule1/WEIGHT -- type: ");   
Serial.println(firebaseData.dataType() ) ; 
String dummy = firebaseData.stringData();
Serial.print(" -- data: ");
Serial.print(dummy); 
char * cstr = new char [dummy.length()+1];
strcpy (cstr, dummy.c_str()); 
Serial.print(" -- data int type: ");
Serial.println(atoi(cstr)) ; 

I have some more nodes to get data from and I've read that lots of Strings are a bad practice. While trying to find out more, I saw the source code and stringData function itself returns a CString:

enter image description here

I feel like I'm doing one step more than what is required! Any suggestions on how to go about this would be very useful!

Try1 Based on the answer from @Majenko, I tried this before adding to the library:

const char* get_cstring() {
  String str = "will it work" ; 
  return str.c_str();
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  const char *new_c = get_cstring(); 
  int len = strlen(new_c);

  for (int i = 0; i < len; i++) {
    Serial.println(new_c[i]);  
    delay(1000);
  }
  Serial.println("----------");
}

But how do I access the contents, because it just prints garbage values; strlen(new_c) gives 2 (I'm guessing that's the amount of storage needed in bytes!?)

Thanks!

0

In returning a String object the Firebase first generates that String object and copies the C string data into it.

If you want to get at the raw C string data you will have to look at adding a new "getter" to the library to return the pointer to that C string data:

I'd write it for you, but since you posted a screenshot of the Firebase function, and the change from that code to the new code is very minor (just change the function name and the return type), I can't copy-and-paste it. And I'm not going to peer at that little image and type it all in again.

Incidentally, internally the Firebase library actually uses std::string, which is a better implementation of the same thing that String does. String was created because the Arduino compiler has no STL, and hence no std::string. Either way they both use dynamic allocation.

4
  • The problem you have is that your str variable is local to the function. It, and the memory allocated within it, gets destroyed when the function returns. So what you have in new_c is a pointer to nothing much. That shouldn't be the case with Firebase, since _data is a std::string that is a member variable, not a local variable.
    – Majenko
    Jan 15 at 11:19
  • I tried with a global String var ; it works! But when I try to use new_c.atoi() with an integer value as input, it fails; so how should the return type be declared!? or where should the change be made to perform those type conversions !? Jan 15 at 12:04
  • @SomasundharamSampath Use atoi(new_c)
    – Majenko
    Jan 15 at 12:06
  • that was very stupid from me!!! Thanks a lot! Looks like I need another primer on C. Jan 15 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.