For the below code snippet
const char* fr_fbdb(char tag[30]) // fn for retrieving data
{
char full_path[120];
const char *_dt ;
strcpy(full_path , base_path);
strcat(full_path , tag);
Serial.print( "retrieving from " );
Serial.println(full_path) ;
Firebase.get(firebaseData, full_path);
_dt = firebaseData.cstrData();
// Serial.print("while ext: ");
// Serial.println(_dt);
return _dt ;
}
void retreive_sch()
{
int no_tag = strlen(*tag) ;
//Serial.print("no. of tags in the DB: ");
//Serial.println(no_tag);
const char *_data[no_tag];
Firebase.get(firebaseData, "/SCHEDULE DETAILS/SELECTED");
sch_no = firebaseData.cstrData();
Serial.print("extracting schedule");
Serial.println(sch_no);
strcat(base_path , sch_no); // base path w/ sch no.
for (int i = 0 ; i < 6 ; i++)
{
_data[i] = fr_fbdb(tag[i]);
Serial.print("while ext: ");
Serial.println(_data[i]);
}
for(int i=0 ; i<6 ; i++)
{
Serial.print("after extraction:");
Serial.println(_data[i]) ;
}
}
This is the output:
retrieving schedule changes -- setup
extracting schedule3
retrieving from /SCHEDULE DETAILS/SCHEDULE3/DATE
while ext: [1609612200000,\"inf\"]
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ FR
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ TO
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/WEIGHT
while ext: 29
retrieving from /SCHEDULE DETAILS/SCHEDULE3/TIME
while ext: \"6:30\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/frequency
while ext: \"-1\"
after extraction:"root":[]
after extraction:\"-1\"
after extraction:keep-alive
after extraction:\"-1\"
after extraction:"root":[]
after extraction:\"-1\"
As you can see, the output of the same variable _data[]
inside that particular function changes.
Any idea why?
1 Answer 1
The problem is these lines of code in your function fr_fddb()
:
Firebase.get(firebaseData, full_path);
_dt = firebaseData.cstrData();
You didn't share enough code to make this clear, but firebaseData
appears to be a global which you reuse. When you call its .cstrData()
method you're getting a pointer to the same buffer each time, and that buffer is overwritten each time you call Firebase.get()
.
You can verify this by printing the pointer value each time through, like so in your retrieve_sch()
function:
for (int i = 0 ; i < 6 ; i++)
{
_data[i] = fr_fbdb(tag[i]);
Serial.print("while ext: ");
Serial.println(_data[i]);
Serial.printf("_data[i] pointer %p\n", _data[i]);
}
You'll likely see that the 6 pointers are identical. The value is changing because you keep reusing the same string.
The easy fix is:
Firebase.get(firebaseData, full_path);
_dt = strdup(firebaseData.cstrData());
This allocates memory and stores in it a duplicate of the string that was fetched from Firebase. Your function will now return that and firebaseData
can safely be reused.
This solution will require you to free that memory at some point when you're doing using it by calling free(_dt);
or whatever you're holding the pointer in when you're done. I leave that as an exercise for you.
const
and what happen and the scope of a locally declare variable within a function._data
is a global var & both set of print statements are within the same Fn. I hv usedconst char* fr_fbdb
bcosfirebaseData.cstrData()
returns a c-string. Here's how I thought the flow was going to be: I callretrieve_sch()
in thesetup()
. Then I get no. of tags fromstrlen(*tag)
(tag
holds strings such as DATE , WEIGHT, etc.). Then using a for loop that callsfr_fbdb()
n no. of times get the req. tags. I also print the value that was retrieved here and in the for loop below. Pls point out where there might be flaws._dt
is a locally declared variable, its scope remain local and when a call is return from the function, whatever stored in the_dt
could be free up and the memory could be override.fr_fbdb()
which is confirmed by the print statements in the 1st for loop ofretreive_sch()
. In the second for loop ofretreive_sch()
the same var,_data
gives different values. My claim is, if there was a pblm (bcos of scope of variables), then it should have been shown in the first print statement. (In case you haven't noticed, I've commented the print statements infr_fbdb()
)