From abcf739e67484aecfb795397353386fed06f5b41 Mon Sep 17 00:00:00 2001 From: suwatchai Date: Mon, 6 Sep 2021 09:39:53 +0700 Subject: [PATCH] Fix setTimestampAsync bug and update the examples. --- README.md | 62 +++++++++---------- examples/Basic/Basic.ino | 35 +++++++++++ examples/BasicCert/BasicCert.ino | 35 +++++++++++ .../NoCallback/NoCallback.ino | 2 + examples/Timestamp/Timestamp.ino | 7 ++- library.json | 16 +++++ library.properties | 2 +- src/FirebaseESP8266.h | 10 +-- src/README.md | 2 +- src/rtdb/FB_RTDB.cpp | 4 +- src/rtdb/FB_RTDB.h | 6 +- 11 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 library.json diff --git a/README.md b/README.md index 2394faf1..41ac4a00 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4390794.svg)](https://doi.org/10.5281/zenodo.4390794) -Google's Firebase Realtime Database Arduino Library for ESP8266 v3.4.3 +Google's Firebase Realtime Database Arduino Library for ESP8266 v3.4.4 This library supports ESP8266 MCU from Espressif. The following are platforms in which libraries are also available. @@ -353,7 +353,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. @@ -455,61 +455,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() functions (since v2.4.0). -* `int i = fbdo.intData();` +* `String s = fbdo.to();` -* `float f = fbdo.floatData();` +* `std::string _s = fbdo.to();` -* `double d = fbdo.doubleData();` +* `const char *str = fbdo.to();` -* `bool b = fbdo.boolData();` +* `bool b = fbdo.to();` -* `String s = fbdo.stringData();` +* `int16_t _i = fbdo.to();` -* `String js = fbdo.jsonString();` +* `int i = fbdo.to();` -* `FirebaseJson &json = fbdo.jsonObject();` +* `double d = fbdo.to();` -* `FirebaseJson *jsonPtr = fbdo.jsonObjectPtr();` +* `float f = fbdo.to();` -* `FirebaseJsonArray &arr = fbdo.jsonArray();` +* `FirebaseJson *json = fbdo.to();` or -* `FirebaseJsonArray *arrPtr = fbdo.jsonArrayPtr();` +* `FirebaseJson json = fbdo.to();` -* `std::vector blob = fbdo.blobData();` +* `FirebaseJsonArray *arr = fbdo.to();` or - * `File file = fbdo.fileStream();` +* `FirebaseJsonArray arr = fbdo.to();` -Or cast to the variables or objects (since v 2.4.0) +* `std::vector *blob = fbdo.to *>();` -* `String s = fbdo.to();` +* `File file = fbdo.to();` -* `std::string _s = fbdo.to();` +Or through the legacy methods -* `const char *str = fbdo.to();` +* `int i = fbdo.intData();` -* `bool b = fbdo.to();` +* `float f = fbdo.floatData();` -* `int16_t _i = fbdo.to();` +* `double d = fbdo.doubleData();` -* `int i = fbdo.to();` +* `bool b = fbdo.boolData();` -* `double d = fbdo.to();` +* `String s = fbdo.stringData();` -* `float f = fbdo.to();` +* `String js = fbdo.jsonString();` -* `FirebaseJson *json = fbdo.to(); //recommend to cast to pointer to object.` or +* `FirebaseJson &json = fbdo.jsonObject();` -* `FirebaseJson json = fbdo.to();` +* `FirebaseJson *jsonPtr = fbdo.jsonObjectPtr();` -* `FirebaseJsonArray *arr = fbdo.to(); //recommend to cast to pointer to object.` or +* `FirebaseJsonArray &arr = fbdo.jsonArray();` -* `FirebaseJsonArray arr = fbdo.to();` +* `FirebaseJsonArray *arrPtr = fbdo.jsonArrayPtr();` -* `std::vector *blob = fbdo.to *>();` +* `std::vector blob = fbdo.blobData();` -* `File file = fbdo.to();` + * `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). @@ -573,7 +573,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.to()`. The file systems for flash and sd memory can be changed in [**FirebaseFS.h**](/src/FirebaseFS.h). diff --git a/examples/Basic/Basic.ino b/examples/Basic/Basic.ino index 957202ba..3b7f0e42 100644 --- a/examples/Basic/Basic.ino +++ b/examples/Basic/Basic.ino @@ -147,3 +147,38 @@ 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.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. + * + */ diff --git a/examples/BasicCert/BasicCert.ino b/examples/BasicCert/BasicCert.ino index d35901c4..66ae252a 100644 --- a/examples/BasicCert/BasicCert.ino +++ b/examples/BasicCert/BasicCert.ino @@ -203,3 +203,38 @@ 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.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. + * + */ \ No newline at end of file diff --git a/examples/DataChangesListener/NoCallback/NoCallback.ino b/examples/DataChangesListener/NoCallback/NoCallback.ino index e1151c07..0b01adc9 100644 --- a/examples/DataChangesListener/NoCallback/NoCallback.ino +++ b/examples/DataChangesListener/NoCallback/NoCallback.ino @@ -100,6 +100,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.readStream(stream)) Serial.printf("sream read error, %s\n\n", stream.errorReason().c_str()); diff --git a/examples/Timestamp/Timestamp.ino b/examples/Timestamp/Timestamp.ino index af6c0f1d..19d8d45c 100644 --- a/examples/Timestamp/Timestamp.ino +++ b/examples/Timestamp/Timestamp.ino @@ -103,11 +103,14 @@ void loop() 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()); - //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()); } diff --git a/library.json b/library.json new file mode 100644 index 00000000..50317b1b --- /dev/null +++ b/library.json @@ -0,0 +1,16 @@ +{ + "name": "Firebase Arduino Client Library for ESP8266", + "version": "3.4.4", + "keywords": "communication, REST, esp8266, arduino", + "description": "This client library provides the complete, fast, secured and reliable operations to read, store, update, delete, monitor the value changes, backup, restore, read and modify the security rules of the Firebase Realtime database.", + "repository": { + "type": "git", + "url": "https://github.com/mobizt/Firebase-ESP8266.git" + }, + "authors": [{ + "name": "Mobizt", + "email": "k_suwatchai@hotmail.com" + }], + "frameworks": "arduino", + "platforms": "espressif8266" +} diff --git a/library.properties b/library.properties index b90fe799..8486dabc 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=Firebase ESP8266 Client -version=3.4.3 +version=3.4.4 author=Mobizt diff --git a/src/FirebaseESP8266.h b/src/FirebaseESP8266.h index f21c590d..0922b6fb 100644 --- a/src/FirebaseESP8266.h +++ b/src/FirebaseESP8266.h @@ -1,16 +1,16 @@ #ifndef FIREBASE_CLIENT_VERSION -#define FIREBASE_CLIENT_VERSION "3.4.3" +#define FIREBASE_CLIENT_VERSION "3.4.4" #endif /** - * Google's Firebase Realtime Database Arduino Library for ESP8266, v3.4.3 + * Google's Firebase Realtime Database Arduino Library for ESP8266, v3.4.4 * - * Created August 31, 2021 + * Created September 6, 2021 * * Updates: - * - Fix pushTimestamp bad request issue. - * - Update timestamp example. + * - Fix setTimestampAsync bug and update the examples. + * * * This library provides ESP8266 to perform REST API by GET PUT, POST, PATCH, DELETE data from/to with Google's Firebase database using get, set, update * and delete calls. diff --git a/src/README.md b/src/README.md index cb8ea904..69cd0116 100644 --- a/src/README.md +++ b/src/README.md @@ -1,7 +1,7 @@ # Firebase Realtime Database Arduino Library for ESP8266 -Google's Firebase Realtime Database Arduino Library for ESP8266 v3.4.3 +Google's Firebase Realtime Database Arduino Library for ESP8266 v3.4.4 ## Global functions diff --git a/src/rtdb/FB_RTDB.cpp b/src/rtdb/FB_RTDB.cpp index 89b3fcbb..1e35babf 100644 --- a/src/rtdb/FB_RTDB.cpp +++ b/src/rtdb/FB_RTDB.cpp @@ -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) diff --git a/src/rtdb/FB_RTDB.h b/src/rtdb/FB_RTDB.h index 43bb73a2..ddccd85d 100644 --- a/src/rtdb/FB_RTDB.h +++ b/src/rtdb/FB_RTDB.h @@ -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) @@ -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 - 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. *