Skip to content

Commit

Permalink
Fix RTDB setTimestampAsync bug #123 and update the examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
mobizt committed Sep 6, 2021
1 parent 0e1981f commit 87ce3cc
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 46 deletions.
62 changes: 31 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Firebase Arduino Client Library for ESP8266 and ESP32


Google's Firebase Arduino Client Library for ESP8266 and ESP32 v2.4.5
Google's Firebase Arduino Client Library for ESP8266 and ESP32 v2.4.6


This library supports ESP8266 and ESP32 MCU from Espressif. The following are platforms in which the libraries are also available (RTDB only).
Expand Down Expand Up @@ -324,7 +324,7 @@ Once the auth token is importance and when it was created and ready for authenti
The legacy token size is relatively small, only 40 bytes, result in smallest header to send, while the size of id token generated using Email/Password is quite large, approx. 900 bytes. result in larger header to send.


There is a compromise between the speed of data transfer and the Rx/Tx buffer which then reduced the free memory available especially in ESp8266.
There is a compromise between the speed of data transfer and the Rx/Tx buffer which then reduced the free memory available especially in ESP8266.


When the reserved SSL client Rx/Tx buffer is smaller than the size of data to be transmitted, the data need to be sent as multiple chunks which required more transmission time.
Expand Down Expand Up @@ -440,61 +440,61 @@ The String of type returns from `fbdo.dataType()` can be string, boolean, int, f
The enum value type, fb_esp_rtdb_data_type returns from `fbdo.dataTypeEnum()` can be fb_esp_rtdb_data_type_null (1), fb_esp_rtdb_data_type_integer, fb_esp_rtdb_data_type_float, fb_esp_rtdb_data_type_double, fb_esp_rtdb_data_type_boolean, fb_esp_rtdb_data_type_string, fb_esp_rtdb_data_type_json, fb_esp_rtdb_data_type_array, fb_esp_rtdb_data_type_blob, and fb_esp_rtdb_data_type_file (10)


The database data's payload (response) can be read or access through the following FirebaseData object's functions.
The database data's payload (response) can be read or access through the casting value from FirebaseData object with to<type>() functions (since v2.4.0).

* `int i = fbdo.intData();`
* `String s = fbdo.to<String>();`

* `float f = fbdo.floatData();`
* `std::string _s = fbdo.to<std::string>();`

* `double d = fbdo.doubleData();`
* `const char *str = fbdo.to<const char *>();`

* `bool b = fbdo.boolData();`
* `bool b = fbdo.to<bool>();`

* `String s = fbdo.stringData();`
* `int16_t _i = fbdo.to<int16_t>();`

* `String js = fbdo.jsonString();`
* `int i = fbdo.to<int>();`

* `FirebaseJson &json = fbdo.jsonObject();`
* `double d = fbdo.to<double>();`

* `FirebaseJson *jsonPtr = fbdo.jsonObjectPtr();`
* `float f = fbdo.to<float>();`

* `FirebaseJsonArray &arr = fbdo.jsonArray();`
* `FirebaseJson *json = fbdo.to<FirebaseJson *>();` or

* `FirebaseJsonArray *arrPtr = fbdo.jsonArrayPtr();`
* `FirebaseJson json = fbdo.to<FirebaseJson>();`

* `std::vector<uint8_t> blob = fbdo.blobData();`
* `FirebaseJsonArray *arr = fbdo.to<FirebaseJsonArray *>();` or

* `File file = fbdo.fileStream();`
* `FirebaseJsonArray arr = fbdo.to<FirebaseJsonArray>();`

Or cast to the variables or objects (since v 2.4.0)
* `std::vector<uint8_t> *blob = fbdo.to<std::vector<uint8_t> *>();`

* `String s = fbdo.to<String>();`
* `File file = fbdo.to<File>();`

* `std::string _s = fbdo.to<std::string>();`
Or through the legacy methods

* `const char *str = fbdo.to<const char *>();`
* `int i = fbdo.intData();`

* `bool b = fbdo.to<bool>();`
* `float f = fbdo.floatData();`

* `int16_t _i = fbdo.to<int16_t>();`
* `double d = fbdo.doubleData();`

* `int i = fbdo.to<int>();`
* `bool b = fbdo.boolData();`

* `double d = fbdo.to<double>();`
* `String s = fbdo.stringData();`

* `float f = fbdo.to<float>();`
* `String js = fbdo.jsonString();`

* `FirebaseJson *json = fbdo.to<FirebaseJson *>(); //recommend to cast to pointer to object.` or
* `FirebaseJson &json = fbdo.jsonObject();`

* `FirebaseJson json = fbdo.to<FirebaseJson>();`
* `FirebaseJson *jsonPtr = fbdo.jsonObjectPtr();`

* `FirebaseJsonArray *arr = fbdo.to<FirebaseJsonArray *>(); //recommend to cast to pointer to object.` or
* `FirebaseJsonArray &arr = fbdo.jsonArray();`

* `FirebaseJsonArray arr = fbdo.to<FirebaseJsonArray>();`
* `FirebaseJsonArray *arrPtr = fbdo.jsonArrayPtr();`

* `std::vector<uint8_t> *blob = fbdo.to<std::vector<uint8_t> *>();`
* `std::vector<uint8_t> blob = fbdo.blobData();`

* `File file = fbdo.to<File>();`
* `File file = fbdo.fileStream();`


Read the data which its type does not match the data type in the database from above functions will return empty (string, object or array).
Expand Down Expand Up @@ -557,7 +557,7 @@ ETag at any node can be read through `Firebase.RTDB.getETag`. ETag value change
The server's **Timestamp** can be stored in the database through `Firebase.RTDB.setTimestamp`.
The returned **Timestamp** value can get from `fbdo.intData()`.
The returned **Timestamp** value can get from `fbdo.fbdo.to<int>()`.
The file systems for flash and sd memory can be changed in [**FirebaseFS.h**](/src/FirebaseFS.h).
Expand Down
37 changes: 37 additions & 0 deletions examples/RTDB/Basic/Basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,43 @@ void loop()
//fb_esp_rtdb_data_type_boolean, fb_esp_rtdb_data_type_string, fb_esp_rtdb_data_type_json,
//fb_esp_rtdb_data_type_array, fb_esp_rtdb_data_type_blob, and fb_esp_rtdb_data_type_file (10)


count++;
}
}



/// PLEASE AVOID THIS ////

//Please avoid the following inappropriate and inefficient use cases
/**
*
* 1. Call get repeatedly inside the loop without the appropriate timing for execution provided e.g. millis() or conditional checking,
* where delay should be avoided.
*
* Every time get was called, the request header need to be sent to server which its size depends on the authentication method used,
* and costs your data usage.
*
* Please use stream function instead for this use case.
*
* 2. Using the single FirebaseData object to call different type functions as above example without the appropriate
* timing for execution provided in the loop i.e., repeatedly switching call between get and set functions.
*
* In addition to costs the data usage, the delay will be involved as the session needs to be closed and opened too often
* due to the HTTP method (GET, PUT, POST, PATCH and DELETE) was changed in the incoming request.
*
*
* Please reduce the use of swithing calls by store the multiple values to the JSON object and store it once on the database.
*
* Or calling continuously "set" or "setAsync" functions without "get" called in between, and calling get continuously without set
* called in between.
*
* If you needed to call arbitrary "get" and "set" based on condition or event, use another FirebaseData object to avoid the session
* closing and reopening.
*
* 3. Use of delay or hidden delay or blocking operation to wait for hardware ready in the third party sensor libraries, together with stream functions e.g. Firebase.RTDB.readStream and fbdo.streamAvailable in the loop.
*
* Please use non-blocking mode of sensor libraries (if available) or use millis instead of delay in your code.
*
*/
34 changes: 34 additions & 0 deletions examples/RTDB/BasicCert/BasicCert.ino
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,37 @@ void loop()
count++;
}
}

/// PLEASE AVOID THIS ////

//Please avoid the following inappropriate and inefficient use cases
/**
*
* 1. Call get repeatedly inside the loop without the appropriate timing for execution provided e.g. millis() or conditional checking,
* where delay should be avoided.
*
* Every time get was called, the request header need to be sent to server which its size depends on the authentication method used,
* and costs your data usage.
*
* Please use stream function instead for this use case.
*
* 2. Using the single FirebaseData object to call different type functions as above example without the appropriate
* timing for execution provided in the loop i.e., repeatedly switching call between get and set functions.
*
* In addition to costs the data usage, the delay will be involved as the session needs to be closed and opened too often
* due to the HTTP method (GET, PUT, POST, PATCH and DELETE) was changed in the incoming request.
*
*
* Please reduce the use of swithing calls by store the multiple values to the JSON object and store it once on the database.
*
* Or calling continuously "set" or "setAsync" functions without "get" called in between, and calling get continuously without set
* called in between.
*
* If you needed to call arbitrary "get" and "set" based on condition or event, use another FirebaseData object to avoid the session
* closing and reopening.
*
* 3. Use of delay or hidden delay or blocking operation to wait for hardware ready in the third party sensor libraries, together with stream functions e.g. Firebase.RTDB.readStream and fbdo.streamAvailable in the loop.
*
* Please use non-blocking mode of sensor libraries (if available) or use millis instead of delay in your code.
*
*/
35 changes: 35 additions & 0 deletions examples/RTDB/BasicEthernetESP32/BasicEthernetESP32.ino
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,41 @@ void testFirebase()
count++;
}

/// PLEASE AVOID THIS ////

//Please avoid the following inappropriate and inefficient use cases
/**
*
* 1. Call get repeatedly inside the loop without the appropriate timing for execution provided e.g. millis() or conditional checking,
* where delay should be avoided.
*
* Every time get was called, the request header need to be sent to server which its size depends on the authentication method used,
* and costs your data usage.
*
* Please use stream function instead for this use case.
*
* 2. Using the single FirebaseData object to call different type functions as above example without the appropriate
* timing for execution provided in the loop i.e., repeatedly switching call between get and set functions.
*
* In addition to costs the data usage, the delay will be involved as the session needs to be closed and opened too often
* due to the HTTP method (GET, PUT, POST, PATCH and DELETE) was changed in the incoming request.
*
*
* Please reduce the use of swithing calls by store the multiple values to the JSON object and store it once on the database.
*
* Or calling continuously "set" or "setAsync" functions without "get" called in between, and calling get continuously without set
* called in between.
*
* If you needed to call arbitrary "get" and "set" based on condition or event, use another FirebaseData object to avoid the session
* closing and reopening.
*
* 3. Use of delay or hidden delay or blocking operation to wait for hardware ready in the third party sensor libraries, together with stream functions e.g. Firebase.RTDB.readStream and fbdo.streamAvailable in the loop.
*
*
* Please use non-blocking mode of sensor libraries (if available) or use millis instead of delay in your code.
*
*/

void setup()
{

Expand Down
2 changes: 2 additions & 0 deletions examples/RTDB/DataChangesListener/NoCallback/NoCallback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ void loop()
if (!Firebase.ready())
return;

//Please avoid to use delay or any third party libraries that use delay internally to wait for hardware to be ready in this loop.

if (!Firebase.RTDB.readStream(&stream))
Serial.printf("sream read error, %s\n\n", stream.errorReason().c_str());

Expand Down
9 changes: 6 additions & 3 deletions examples/RTDB/Timestamp/Timestamp.ino
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,17 @@ void loop()
taskCompleted = true;

Serial.printf("Set timestamp... %s\n", Firebase.RTDB.setTimestamp(&fbdo, "/test/timestamp") ? "ok" : fbdo.errorReason().c_str());

if (fbdo.httpCode() == FIREBASE_ERROR_HTTP_CODE_OK)
{
//Timestamp saved in millisecond, get its seconds from intData()

//In setTimestampAsync, the following timestamp will be 0 because the response payload was ignored for all async functions.

//Timestamp saved in millisecond, get its seconds from int value
Serial.print("TIMESTAMP (Seconds): ");
Serial.println(fbdo.to<int>());

//Or print the total milliseconds from doubleData()
//Or print the total milliseconds from double value
//Due to bugs in Serial.print in Arduino library, use printf to print double instead.
printf("TIMESTAMP (milliSeconds): %lld\n", fbdo.to<uint64_t>());
}
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Firebase Arduino Client Library for ESP8266 and ESP32",
"version": "2.4.5",
"version": "2.4.6",
"keywords": "communication, REST, esp32, esp8266, arduino",
"description": "The library supports Firebase products e.g. Realtime database, Cloud Firestore database, Firebase Storage and Google Cloud Storage, Cloud Functions for Firebase and Cloud Messaging.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name=Firebase Arduino Client Library for ESP8266 and ESP32

version=2.4.5
version=2.4.6

author=Mobizt

Expand Down
8 changes: 4 additions & 4 deletions src/Firebase_ESP_Client.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#ifndef FIREBASE_CLIENT_VERSION
#define FIREBASE_CLIENT_VERSION "2.4.5"
#define FIREBASE_CLIENT_VERSION "2.4.6"
#endif

/**
* Google's Firebase ESP Client Main class, Firebase_ESP_Client.h v2.4.5
* Google's Firebase ESP Client Main class, Firebase_ESP_Client.h v2.4.6
*
* This library supports Espressif ESP8266 and ESP32 MCUs
*
* Created September 3, 2021
* Created September 6, 2021
*
* Updates:
* - Fix Firestore getDocument hang bugs #122, and also #112 due to accidently recursive calling the function itself.
* - Fix RTDB setTimestampAsync bug #123 and update the examples.
*
* This work is a part of Firebase ESP Client library
* Copyright (c) 2021 K. Suwatchai (Mobizt)
Expand Down
2 changes: 1 addition & 1 deletion src/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Firebase Arduino Client Library for ESP8266 and ESP32


Google's Firebase Arduino Client Library for ESP8266 and ESP32 v2.4.5
Google's Firebase Arduino Client Library for ESP8266 and ESP32 v2.4.6


The default filessystem used in the library is flash and SD.
Expand Down
4 changes: 2 additions & 2 deletions src/rtdb/FB_RTDB.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* Google's Firebase Realtime Database class, FB_RTDB.cpp version 1.2.2
* Google's Firebase Realtime Database class, FB_RTDB.cpp version 1.2.3
*
* This library supports Espressif ESP8266 and ESP32
*
* Created August 31, 2021
* Created September 6, 2021
*
* This work is a part of Firebase ESP Client library
* Copyright (c) 2021 K. Suwatchai (Mobizt)
Expand Down
6 changes: 3 additions & 3 deletions src/rtdb/FB_RTDB.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* Google's Firebase Realtime Database class, FB_RTDB.h version 1.2.2
* Google's Firebase Realtime Database class, FB_RTDB.h version 1.2.3
*
* This library supports Espressif ESP8266 and ESP32
*
* Created August 31, 2021
* Created September 6, 2021
*
* This work is a part of Firebase ESP Client library
* Copyright (c) 2021 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -925,7 +925,7 @@ class FB_RTDB
bool setTimestamp(FirebaseData *fbdo, T path) { return buildRequest(fbdo, m_put, toString(path), PGM2S(fb_esp_pgm_str_154).get(), d_timestamp, _NO_SUB_TYPE, _NO_REF, _NO_QUERY, _NO_PRIORITY, _NO_ETAG, _NO_ASYNC, _NO_QUEUE); }

template <typename T = const char *>
bool setTimestampAsync(FirebaseData *fbdo, T path) { return buildRequest(fbdo, m_put, toString(path), _NO_PAYLOAD, d_timestamp, _NO_SUB_TYPE, _NO_REF, _NO_QUERY, _NO_PRIORITY, _NO_ETAG, _IS_ASYNC, _NO_QUEUE); }
bool setTimestampAsync(FirebaseData *fbdo, T path) { return buildRequest(fbdo, m_put, toString(path), PGM2S(fb_esp_pgm_str_154).get(), d_timestamp, _NO_SUB_TYPE, _NO_REF, _NO_QUERY, _NO_PRIORITY, _NO_ETAG, _IS_ASYNC, _NO_QUEUE); }

/** Update (patch) the child (s) nodes to the defined node.
*
Expand Down

0 comments on commit 87ce3cc

Please sign in to comment.