Closed mbariola closed 4 years ago
Please share the code that you create the JSON object with timestamp.
No more feedback?
Hi @mobizt
I'm away from the computer till later today. I'll add my code asap
On Sun, Aug 9, 2020, 08:01 mobizt notifications@github.com wrote:
No more feedback?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mobizt/Firebase-ESP32/issues/91#issuecomment-671011079, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFKTX5UWV6NPXPHTBAVRYDR7Y3TFANCNFSM4PX3HEVQ .
Hi @mobizt , thanks for waiting
here is the code. It does not compile (error on the timestamp line) ... as you have seen, I have tried to do it with a FirebaseData too, no luck. probably it's something trivial but I have difficulty understanding the separation of concerns between FirebaseJson objects and FirebaseData ones.
Ideally, I would like to create in memory the JSON object, then push it to a /...../clientID/readings path which will contain N (an array) of the objects I am building
FirebaseData firebaseData; // Firebase Object
FirebaseJsonArray readingsJsonArray;
FirebaseJson testObj;
....
/* code */
// build the obj to send
Firebase.setTimestamp(firebaseData, "/datetime");
for(int i = 0; i< numSteps; i++)
{
readingsJsonArray.add(stepStatus[i]);
}
testObj.set("/readings", readingsJsonArray);
//Firebase.set(firebaseData, "/readings", readingsJsonArray);
testObj.setTimestamp("/readingDateTime");
//Firebase.setTimestamp(firebaseData, "/readingDateTime" );
testObj.set("/gloveID", "DemoGloveID");
//Firebase.set(firebaseData, "/gloveID", "DemoGloveID" );
Firebase.push(firebaseData, readingsSavePath, testObj);
readingsJsonArray.clear();
testObj.clear();
That is because you use the wrong syntax.
The setTimestamp function is not available (not existed) for FirebaseJson object.
The data types i.e. bool, int, float, double, string, JSON object and JSON array object are supported with set and add function of FirebaseJson and FirebaseJsonArray.
The FirebaseJson is the JSON object (class) that used for JSON data manipulation (create, edit and parsing)
and FirebaseJsonArray is the array object (class) which can creat, edit and then add to the JSON object (FirebaseJson).
The FirebaseJsonData (similar to FirebaseData object) is the class object that holds the parsing result when you want to get or extract the value from specific key in the FirebaseJson object.
The Firebase.setTimestamp function is for Firebase class only. This timestamp value was hidden from Firebase web console but you can read its double value (UNIX timestamp value of milliseconds) from specific node with the FirebasegetDouble function as seen in Timestamp.ino example.
To check all supported function please see this.
If you want to set the timestamp to the JSON object, you just use
testObj.set("/readingDateTime", xxxxxxxxxxxx);
Where as xxxxxxxxxxxx is the integer number of timestamp which you need to assign or get it from the system time of the device (NTP server or RTC chip).
This is total difference from Firebase.setTimestamp which you don't need to provide the timestamp value to the function, Firebase will be set it for you automatically at the server side.
Hi @mobizt ,
I understand a little bit better, and that I had a confusion between client set timestamp and firebase set timestamp. So, what I want to achieve, is to create an array of JSON objects. each of the objects is made like this:
So, I seem to understand that
1) I need to copy my normal int array into a FirebaseJsonArray, then add this array to a .... FirebaseJson? (i.e. testObj) 2) Add other key/values pairs to this FirebaseJson object. Is it correct to say that at this moment, the object has not been saved to Firebase and all paths are relative to the object itself?
3) push this object in the firebase path (i.e. save to firebase) where the list of readings is. I am not sure at this point what syntax is best to use. 3.1) If I want to have an explicitly set timestamp from Firebase, how should I specify it while building the object befoee pushing it to firebase?
Thanks
ok, this is the current version of the code.....
for(int i = 0; i< numSteps; i++)
{
readingsJsonArray.add((int)stepStatus[i]);
}
testObj.set("/readings", readingsJsonArray);
testObj.set("/sockID", "DemoSockID");
// TODO: /readingDateTime needs to be set by Firebase server
Firebase.push(firebaseData, readingsSavePath, testObj);
readingsJsonArray.clear(); // will this deallocate the memory / best way to avoid leaks / fragmentation?
testObj.clear();
It works. And I also saw that I can construct the object in memory and push it in one go with Firebase.push.
But I still need to set the readingsDateTime key/value with the Firebase server value . This bit I do not know how to do in a short way.
You can't set the server value in to any json data.
You need to make a single request for set server value timestamp.
Please read the Firebase REST API document.
Ok, so I need to set it on a different call, then read it and put that value in the json, right?
On Tue, Aug 11, 2020, 02:02 mobizt notifications@github.com wrote:
You can't set the server value in to any json data.
You need to make a single request for set server value timestamp.
Please read the Firebase REST API document.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mobizt/Firebase-ESP32/issues/91#issuecomment-671648575, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFKTX2FHM2KJSTE3LZ7WYTSACC77ANCNFSM4PX3HEVQ .
Yes.
The point is, I do not trust the client devices to give me an accurate and consistent timestamp. This is why I need to find the equivalent of Firebase::serverTimestamp (if I recall correctly) EDIT: of this: firebase.database.ServerValue.TIMESTAMP
On Tue, Aug 11, 2020, 02:04 Massimiliano Bariola m.bariola@gmail.com wrote:
Ok, so I need to set it on a different call, then read it and put that value in the json, right?
On Tue, Aug 11, 2020, 02:02 mobizt notifications@github.com wrote:
You can't set the server value in to any json data.
You need to make a single request for set server value timestamp.
Please read the Firebase REST API document.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mobizt/Firebase-ESP32/issues/91#issuecomment-671648575, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFKTX2FHM2KJSTE3LZ7WYTSACC77ANCNFSM4PX3HEVQ .
Ok got it. Thanks!
On Tue, Aug 11, 2020, 02:05 mobizt notifications@github.com wrote:
Yes.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mobizt/Firebase-ESP32/issues/91#issuecomment-671649664, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFKTX6UIT7WMDB5UX747MDSACDNRANCNFSM4PX3HEVQ .
For server timestamp, the pay load for the request sent to server must be {".sv":"timestamp"} which should not mixed by any user data.
I am unsure how to use it. Can you provide a line of code passing that payload?
Alternatively, does Firebase provide a current timestamp that can be read? (so that I can skip the "setting the timestamp first" part)? Thanks
On Tue, Aug 11, 2020, 02:10 mobizt notifications@github.com wrote:
For server timestamp, the pay load for the request sent to server must be {".sv":"timestamp"} which should not mixed by any user data.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mobizt/Firebase-ESP32/issues/91#issuecomment-671651020, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFKTX3NJDMUKOJXA66LGELSACD6XANCNFSM4PX3HEVQ .
No, I only explain what the server timestamp payload (data that being send to server) should be.
When you call the Firebasse.setTimestamp function, the library sent this JSON {".sv":"timestamp"} to Firebase server. This kind of JSON payload is treated like a command not a user data.
Hi @mobizt , yes that I understood, but had problems to find out how to make sure to pass that special value at the time of object creation.
So I experimented a little with what you said, and found a way. I don't know if it's the most elegant one, but it works and it does all with just one call to firebase
FirebaseJson testObj;
for(int i = 0; i< numSteps; i++)
{
readingsJsonArray.add((int)stepStatus[i]);
}
testObj.set("/readings", readingsJsonArray);
testObj.set("/shirtID", "DemoShirtID");
testObj.set("/readingDateTime/.sv", "timestamp");
Firebase.push(firebaseData, readingsSavePath, testObj) || Serial.println(firebaseData.errorReason());
readingsJsonArray.clear();
testObj.clear();
Thanks for your input, it nudged me in the right direction. Cheers!
You can trust the device time as you can get the time from NTP server that give you the same and accurate timestamp for every client device.
The millisecond timestamp is only the second timestamp multiplied by 1000.
Some Time library provides more precision timestamp from NTP server with the request/response time delay compensation.
Unfortunately I am developing a battery powered device and thus it is most of the time in super low power mode and offline. it comes online only to send data in bursts, then goes offline again. Any extra call shortens battery life. But I found a way that works (see comment above)! thanks for the info
@mbariola Thanks for posting, I had the same question. Your implementation worked for me too. Using the '.set' with a path instead of the '.add' method on the json object is the trick. Also, thanks @mobizt for this library, works great!
Hi there @mobizt
I need to save a moderately complex JSON object, which has an array of integers, some integers, and some strings. By following your examples, I am able to set a JSON object and commit it in one go.
This JSON object also has a timestamp, but I was not able to set it in the json object to commit. Only to do it in 2 steps: first the object without the timestamp, then fetching the object key and save the timestamp in it by giving a path within the object I just created.
Is there a way to do it in just one step?
to clarify I need to save something like this at /clients/config/[clientName]/current and would like it to happen in one go
Many thanks