From 704a2959a649ffe2635ae05615d66c3372af9fb1 Mon Sep 17 00:00:00 2001 From: suwatchai Date: Sun, 21 Feb 2021 21:55:18 +0700 Subject: [PATCH] Fix the RTDB session close handle crashed and others bugs fixed. --- README.md | 2 +- .../Access_Token_from_File.ino | 5 + .../Import_Documents/Import_Documents.ino | 2 +- examples/README.md | 4 +- library.json | 2 +- library.properties | 2 +- src/Firebase_ESP_Client.cpp | 4 +- src/Firebase_ESP_Client.h | 4 +- src/README.md | 2 +- src/common.h | 18 +++- src/firestore/FB_Firestore.cpp | 13 ++- src/firestore/FB_Firestore.h | 5 +- src/functions/FB_Functions.cpp | 14 ++- src/functions/FB_Functions.h | 5 +- src/gcs/GCS.cpp | 75 +++++++++------ src/gcs/GCS.h | 5 +- src/message/FCM.cpp | 69 ++++++++++---- src/message/FCM.h | 13 ++- src/rtdb/FB_RTDB.cpp | 91 +++++++++---------- src/rtdb/FB_RTDB.h | 5 +- src/session/FB_Session.cpp | 22 +++-- src/session/FB_Session.h | 4 +- src/signer/Signer.cpp | 16 +++- src/storage/FCS.cpp | 16 ++-- src/storage/FCS.h | 5 +- 25 files changed, 251 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index 90ba3d55f..362f3a1fe 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Firebase Arduino Client Library for ESP8266 and ESP32 -Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.2 +Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.3 This library supports ESP8266 and ESP32 MCU from Espressif. The following are platforms in which the libraries are also available (RTDB only). diff --git a/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino b/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino index a0e37ebff..a885c2077 100644 --- a/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino +++ b/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino @@ -84,6 +84,11 @@ void setup() /** The user UID set to empty to sign in as admin */ auth.token.uid = ""; + /** The scope of the OAuth2.0 authentication + * If you wan't this access token for others Google Cloud Services. + */ + //config.signer.tokens.scope = "Google Scope 1 Url, Google Scope 2 Url,.."; + Firebase.reconnectWiFi(true); /* Now we start to signin using access token */ diff --git a/examples/Firestore/Import_Documents/Import_Documents.ino b/examples/Firestore/Import_Documents/Import_Documents.ino index 4e39c9607..d08659073 100644 --- a/examples/Firestore/Import_Documents/Import_Documents.ino +++ b/examples/Firestore/Import_Documents/Import_Documents.ino @@ -89,7 +89,7 @@ void setup() Serial.println("------------------------------------"); Serial.println("Import documents from the Storage bucket..."); - if (Firebase.Firestore.importDocuments(&fbdo, FIREBASE_PROJECT_ID, "" /* databaseId can be (default) or empty */, STORAGE_BUCKET_ID, "test_path" /* The path in the Firebase Storage bucket to store the data */, "" /* Which collection ids to export. Unspecified means all collections. */)) + if (Firebase.Firestore.importDocuments(&fbdo, FIREBASE_PROJECT_ID, "" /* databaseId can be (default) or empty */, STORAGE_BUCKET_ID, "test_path" /* The path in the Firebase Storage bucket to store the data */, "" /* Which collection ids to import. Unspecified means all collections. */)) { Serial.println("PASSED"); Serial.println("------------------------------------"); diff --git a/examples/README.md b/examples/README.md index c45b35288..9abc4cf53 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,11 +1,11 @@ # Migrate from Firebase-ESP32 or Firebase-ESP8266 library to Firebase-ESP-Client library -This library includes the Firebase Storage fnctions and the Firebase Cloud Messageing upgrades. +This library includes the Firebase and Google Cloud Storage fnctions, Cloud Firestore, Cloud Functions and the Firebase Cloud Messageing upgrades. The major changes from Firebase-ESP32 or Firebase-ESP8266 library are. -* All Firebase Realtime database functions moved from Firebase class to Firebase.RTDB class. +* All Firebase Realtime database functions moved from Firebase class to Firebase.RTDB member class. * All parameters in RTDB functions are the pointer to the variables unless the String type value. diff --git a/library.json b/library.json index b5b17eeea..437647ff7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Firebase Arduino Client Library for ESP8266 and ESP32", - "version": "2.0.2", + "version": "2.0.3", "keywords": "communication, REST, esp32, esp8266, arduino", "description": "This client library provides the functions to work with Firebase Realtime database, Firestore, Storage and Cloud messaging.", "repository": { diff --git a/library.properties b/library.properties index 87391488f..d4f184ae5 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=Firebase Arduino Client Library for ESP8266 and ESP32 -version=2.0.2 +version=2.0.3 author=Mobizt diff --git a/src/Firebase_ESP_Client.cpp b/src/Firebase_ESP_Client.cpp index 46b78d819..6f037095e 100644 --- a/src/Firebase_ESP_Client.cpp +++ b/src/Firebase_ESP_Client.cpp @@ -1,9 +1,9 @@ /** - * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.2 + * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) diff --git a/src/Firebase_ESP_Client.h b/src/Firebase_ESP_Client.h index 83ad5bc73..9f3215850 100644 --- a/src/Firebase_ESP_Client.h +++ b/src/Firebase_ESP_Client.h @@ -1,9 +1,9 @@ /** - * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.2 + * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) diff --git a/src/README.md b/src/README.md index 3d1127855..a7331c085 100644 --- a/src/README.md +++ b/src/README.md @@ -1,7 +1,7 @@ # Firebase Arduino Client Library for ESP8266 and ESP32 -Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.2 +Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.3 ## Global functions diff --git a/src/common.h b/src/common.h index 2faad5e07..98425821d 100644 --- a/src/common.h +++ b/src/common.h @@ -133,6 +133,13 @@ enum fb_esp_method m_set_priority, }; +enum fb_esp_http_connection_type +{ + fb_esp_http_connection_type_undefined, + fb_esp_http_connection_type_keep_alive, + fb_esp_http_connection_type_close +}; + enum fb_esp_settings_provider_type { auth_provider_type_login, @@ -387,6 +394,7 @@ struct fb_esp_auth_token_info_t std::string legacy_token; std::string auth_type; std::string jwt; + std::string scope; unsigned long expires = 0; fb_esp_auth_token_type token_type = token_type_undefined; fb_esp_auth_token_status status = token_status_uninitialized; @@ -551,7 +559,7 @@ struct fb_esp_fcs_file_list_item_t typedef struct fb_esp_gcs_upload_status_info_t { - size_t progress; + size_t progress = 0; fb_esp_gcs_upload_status status = fb_esp_gcs_upload_status_unknown; std::string localFileName = ""; std::string remoteFileName = ""; @@ -583,11 +591,12 @@ struct fb_esp_rtdb_info_t bool stream_data_changed = false; bool stream_path_changed = false; bool data_available = false; - bool keep_alive = false; + fb_esp_http_connection_type http_req_conn_type = fb_esp_http_connection_type_undefined; + fb_esp_http_connection_type http_resp_conn_type = fb_esp_http_connection_type_undefined; bool data_mismatch = false; bool path_not_found = false; bool pause = false; - bool stream_stop = false; + bool stream_stop = true; uint8_t connection_status = 0; uint32_t queue_ID = 0; @@ -932,6 +941,9 @@ struct fb_esp_session_info_t bool chunked_encoding = false; bool connected = false; bool classic_request = false; + std::string host = ""; + unsigned long last_conn_ms = 0; + const uint32_t conn_timeout = 3 * 60 * 1000; uint16_t resp_size = 2048; int http_code = -1000; diff --git a/src/firestore/FB_Firestore.cpp b/src/firestore/FB_Firestore.cpp index a21f680bd..89aa4b768 100644 --- a/src/firestore/FB_Firestore.cpp +++ b/src/firestore/FB_Firestore.cpp @@ -1,9 +1,9 @@ /** - * Google's Cloud Firestore class, Forestore.cpp version 1.0.2 + * Google's Cloud Firestore class, Forestore.cpp version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -534,12 +534,15 @@ bool FB_Firestore::firestore_sendRequest(FirebaseData *fbdo, struct fb_esp_fires if (ret == 0) { + fbdo->_ss.connected = true; if (handleResponse(fbdo)) { Signer.getCfg()->_int.fb_processing = false; return true; } } + else + fbdo->_ss.connected = false; Signer.getCfg()->_int.fb_processing = false; @@ -548,12 +551,14 @@ bool FB_Firestore::firestore_sendRequest(FirebaseData *fbdo, struct fb_esp_fires void FB_Firestore::rescon(FirebaseData *fbdo, const char *host) { - if (!fbdo->_ss.connected || fbdo->_ss.con_mode != fb_esp_con_mode_firestore || strcmp(host, _host.c_str()) != 0) + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.con_mode != fb_esp_con_mode_firestore || strcmp(host, fbdo->_ss.host.c_str()) != 0) { + fbdo->_ss.last_conn_ms = millis(); fbdo->closeSession(); fbdo->setSecure(); } - _host = host; + + fbdo->_ss.host = host; fbdo->_ss.con_mode = fb_esp_con_mode_firestore; } diff --git a/src/firestore/FB_Firestore.h b/src/firestore/FB_Firestore.h index ea8291b1d..ae0d6e025 100644 --- a/src/firestore/FB_Firestore.h +++ b/src/firestore/FB_Firestore.h @@ -1,9 +1,9 @@ /** - * Google's Cloud Firestore class, Forestore.h version 1.0.2 + * Google's Cloud Firestore class, Forestore.h version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -247,7 +247,6 @@ class FB_Firestore private: UtilsClass *ut = nullptr; - std::string _host = ""; void begin(UtilsClass *u); void rescon(FirebaseData *fbdo, const char *host); bool connect(FirebaseData *fbdo); diff --git a/src/functions/FB_Functions.cpp b/src/functions/FB_Functions.cpp index 429d771bb..36640f271 100644 --- a/src/functions/FB_Functions.cpp +++ b/src/functions/FB_Functions.cpp @@ -1,9 +1,9 @@ /** - * Google's Cloud Functions class, Functions.cpp version 1.0.1 + * Google's Cloud Functions class, Functions.cpp version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -816,7 +816,7 @@ bool FB_Functions::functions_sendRequest(FirebaseData *fbdo, struct fb_esp_funct } ut->appendP(header, fb_esp_pgm_str_32); - ut->appendP(header, fb_esp_pgm_str_36); + ut->appendP(header, fb_esp_pgm_str_34); ut->appendP(header, fb_esp_pgm_str_21); fbdo->_ss.http_code = FIREBASE_ERROR_HTTPC_ERROR_NOT_CONNECTED; @@ -829,6 +829,7 @@ bool FB_Functions::functions_sendRequest(FirebaseData *fbdo, struct fb_esp_funct if (ret == 0) { + fbdo->_ss.connected = true; if (req->requestType == fb_esp_functions_request_type_upload) { int available = Signer.getCfg()->_int.fb_file.available(); @@ -875,6 +876,8 @@ bool FB_Functions::functions_sendRequest(FirebaseData *fbdo, struct fb_esp_funct return true; } } + else + fbdo->_ss.connected = false; Signer.getCfg()->_int.fb_processing = false; return false; @@ -882,12 +885,13 @@ bool FB_Functions::functions_sendRequest(FirebaseData *fbdo, struct fb_esp_funct void FB_Functions::rescon(FirebaseData *fbdo, const char *host) { - if (!fbdo->_ss.connected || fbdo->_ss.con_mode != fb_esp_con_mode_functions || strcmp(host, _host.c_str()) != 0) + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.con_mode != fb_esp_con_mode_functions || strcmp(host, fbdo->_ss.host.c_str()) != 0) { + fbdo->_ss.last_conn_ms = millis(); fbdo->closeSession(); fbdo->setSecure(); } - _host = host; + fbdo->_ss.host = host; fbdo->_ss.con_mode = fb_esp_con_mode_functions; } diff --git a/src/functions/FB_Functions.h b/src/functions/FB_Functions.h index 8e3deb9ee..0a9a5c3ad 100644 --- a/src/functions/FB_Functions.h +++ b/src/functions/FB_Functions.h @@ -1,9 +1,9 @@ /** - * Google's Cloud Functions class, Functions.h version 1.0.1 + * Google's Cloud Functions class, Functions.h version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -262,7 +262,6 @@ class FB_Functions bool listOperations(FirebaseData *fbdo, const char *filter, int pageSize, const char *pageToken); private: - std::string _host = ""; fb_esp_functions_status _function_status = fb_esp_functions_status_CLOUD_FUNCTION_STATUS_UNSPECIFIED; UtilsClass *ut = nullptr; unsigned long _lasPollMs = 0; diff --git a/src/gcs/GCS.cpp b/src/gcs/GCS.cpp index c371f29de..a3846d780 100644 --- a/src/gcs/GCS.cpp +++ b/src/gcs/GCS.cpp @@ -1,9 +1,9 @@ /** - * Google's Cloud Storage class, GCS.cpp version 1.0.1 + * Google's Cloud Storage class, GCS.cpp version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -142,7 +142,19 @@ bool GG_CloudStorage::sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_t *r } } - return gcs_sendRequest(fbdo, req); + bool ret = gcs_sendRequest(fbdo, req); + if (!ret && (req->requestType == fb_esp_gcs_request_type_upload_simple || req->requestType == fb_esp_gcs_request_type_upload_multipart || req->requestType == fb_esp_gcs_request_type_upload_resumable_init)) + { + fbdo->_ss.gcs.cbInfo.status = fb_esp_gcs_upload_status_error; + UploadStatusInfo in; + in.localFileName = req->localFileName; + in.remoteFileName = req->remoteFileName; + in.status = fb_esp_gcs_upload_status_error; + in.progress = 0; + in.errorMsg = fbdo->errorReason().c_str(); + sendCallback(fbdo, in, req->callback, req->statusInfo); + } + return ret; } bool GG_CloudStorage::download(FirebaseData *fbdo, const char *bucketID, const char *remoteFileName, const char *localFileName, fb_esp_mem_storage_type storageType, StorageGetOptions *options) @@ -197,12 +209,13 @@ bool GG_CloudStorage::gcs_connect(FirebaseData *fbdo) void GG_CloudStorage::rescon(FirebaseData *fbdo, const char *host) { - if (!fbdo->_ss.connected || fbdo->_ss.con_mode != fb_esp_con_mode_gc_storage || strcmp(host, _host.c_str()) != 0) + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.con_mode != fb_esp_con_mode_gc_storage || strcmp(host, fbdo->_ss.host.c_str()) != 0) { + fbdo->_ss.last_conn_ms = millis(); fbdo->closeSession(); fbdo->setSecure(); } - _host = host; + fbdo->_ss.host = host; fbdo->_ss.con_mode = fb_esp_con_mode_gc_storage; } @@ -604,6 +617,7 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ if (ret == 0) { + fbdo->_ss.connected = true; if (req->requestType == fb_esp_gcs_request_type_upload_simple || req->requestType == fb_esp_gcs_request_type_upload_multipart) { @@ -630,7 +644,11 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ byteRead += read; reportUpploadProgress(fbdo, req, byteRead); if (fbdo->httpClient.stream()->write(buf, read) != read) + { + fbdo->_ss.connected = false; break; + } + available = Signer.getCfg()->_int.fb_file.available(); } delete[] buf; @@ -672,7 +690,11 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ available = bufLen; read = Signer.getCfg()->_int.fb_file.read(buf, available); if (fbdo->httpClient.stream()->write(buf, read) != read) + { + fbdo->_ss.connected = false; break; + } + byteRead += read; reportUpploadProgress(fbdo, req, byteRead); available = Signer.getCfg()->_int.fb_file.available(); @@ -684,29 +706,18 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ Signer.getCfg()->_int.fb_file.close(); } - ret = handleResponse(fbdo, req); - - if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_gcs_request_type_download) - Signer.getCfg()->_int.fb_file.close(); - - Signer.getCfg()->_int.fb_processing = false; - - if (ret) + if (fbdo->_ss.connected) { + ret = handleResponse(fbdo, req); fbdo->closeSession(); - - if (req->requestType == fb_esp_gcs_request_type_upload_simple || req->requestType == fb_esp_gcs_request_type_upload_multipart) - { - UploadStatusInfo in; - in.localFileName = req->localFileName; - in.remoteFileName = req->remoteFileName; - in.status = fb_esp_gcs_upload_status_complete; - in.progress = 100; - sendCallback(fbdo, in, req->callback, req->statusInfo); - } - else if (req->requestType == fb_esp_gcs_request_type_upload_resumable_run) + if (ret) { - if (Signer.getCfg()->_int.fb_file.available() == 0) + if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_gcs_request_type_download) + Signer.getCfg()->_int.fb_file.close(); + + Signer.getCfg()->_int.fb_processing = false; + + if (req->requestType == fb_esp_gcs_request_type_upload_simple || req->requestType == fb_esp_gcs_request_type_upload_multipart) { UploadStatusInfo in; in.localFileName = req->localFileName; @@ -715,8 +726,20 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ in.progress = 100; sendCallback(fbdo, in, req->callback, req->statusInfo); } + else if (req->requestType == fb_esp_gcs_request_type_upload_resumable_run) + { + if (Signer.getCfg()->_int.fb_file.available() == 0) + { + UploadStatusInfo in; + in.localFileName = req->localFileName; + in.remoteFileName = req->remoteFileName; + in.status = fb_esp_gcs_upload_status_complete; + in.progress = 100; + sendCallback(fbdo, in, req->callback, req->statusInfo); + } + } + return ret; } - return ret; } } diff --git a/src/gcs/GCS.h b/src/gcs/GCS.h index b0a7d3e9c..0d3d8f3e0 100644 --- a/src/gcs/GCS.h +++ b/src/gcs/GCS.h @@ -1,9 +1,9 @@ /** - * Google's Cloud Storage class, GCS.h version 1.0.1 + * Google's Cloud Storage class, GCS.h version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -142,7 +142,6 @@ class GG_CloudStorage uint32_t gcs_chunkSize = 256 * 1024; bool _resumable_upload_task_enable = false; UtilsClass *ut = nullptr; - std::string _host = ""; std::vector _resumableUploadTasks = std::vector(); size_t _resumableUplaodTaskIndex = 0; diff --git a/src/message/FCM.cpp b/src/message/FCM.cpp index 2c54e386c..0c80c58b0 100644 --- a/src/message/FCM.cpp +++ b/src/message/FCM.cpp @@ -1,9 +1,9 @@ /** - * Google's Firebase Cloud Messaging class, FCM.cpp version 1.0.2 + * Google's Firebase Cloud Messaging class, FCM.cpp version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -40,11 +40,24 @@ FB_CM::~FB_CM() clear(); } -bool FB_CM::init() +bool FB_CM::init(bool clearInt) { if (!Signer.getCfg()) return false; + if (clearInt) + { + if (_ut) + delete _ut; + if (_cfg) + delete _cfg; + if (_auth) + delete _auth; + + _ut = nullptr; + _cfg = nullptr; + _auth = nullptr; + } if (!ut) ut = new UtilsClass(Signer.getCfg()); @@ -53,6 +66,7 @@ bool FB_CM::init() void FB_CM::begin(UtilsClass *u) { + init(true); ut = u; } @@ -64,13 +78,17 @@ void FB_CM::setServerKey(const char *serverKey) bool FB_CM::send(FirebaseData *fbdo, FCM_Legacy_HTTP_Message *msg) { if (!Signer.getCfg()) - return false; + { + _cfg = new FirebaseConfig(); + _auth = new FirebaseAuth(); + _ut = new UtilsClass(_cfg); + ut = _ut; + Signer.begin(_ut, _cfg, _auth); + } if (!init()) return false; - Signer.tokenReady(); - if (_server_key.length() == 0) { fbdo->_ss.http_code = FIREBASE_ERROR_HTTPC_NO_FCM_SERVER_KEY_PROVIDED; @@ -175,7 +193,7 @@ String FB_CM::payload(FirebaseData *fbdo) return fbdo->_ss.fcm.payload.c_str(); } -void FB_CM::fcm_begin(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode) +void FB_CM::fcm_connect(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode) { if (Signer.getTokenType() != token_type_undefined) @@ -191,6 +209,8 @@ void FB_CM::fcm_begin(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode) ut->appendP(host, fb_esp_pgm_str_329); ut->appendP(host, fb_esp_pgm_str_4); ut->appendP(host, fb_esp_pgm_str_120); + + rescon(fbdo, host.c_str()); fbdo->httpClient.begin(host.c_str(), _port); } @@ -1454,6 +1474,18 @@ bool FB_CM::handleResponse(FirebaseData *fbdo) return false; } +void FB_CM::rescon(FirebaseData *fbdo, const char *host) +{ + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.con_mode != fb_esp_con_mode_fcm || strcmp(host, fbdo->_ss.host.c_str()) != 0) + { + fbdo->_ss.last_conn_ms = millis(); + fbdo->closeSession(); + fbdo->setSecure(); + } + fbdo->_ss.host = host; + fbdo->_ss.con_mode = fb_esp_con_mode_fcm; +} + bool FB_CM::handleFCMRequest(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode, std::string &payload) { @@ -1466,10 +1498,13 @@ bool FB_CM::handleFCMRequest(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode, std:: if (fbdo->_ss.rtdb.pause) return true; - if (Signer.config->host.length() == 0) + if (mode == fb_esp_fcm_msg_mode_httpv1) { - fbdo->_ss.http_code = FIREBASE_ERROR_UNINITIALIZED; - return false; + if (Signer.config->host.length() == 0) + { + fbdo->_ss.http_code = FIREBASE_ERROR_UNINITIALIZED; + return false; + } } if (fbdo->_ss.long_running_task > 0) @@ -1483,13 +1518,7 @@ bool FB_CM::handleFCMRequest(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode, std:: Signer.getCfg()->_int.fb_processing = true; - if (!fbdo->_ss.connected || fbdo->_ss.con_mode != fb_esp_con_mode_fcm) - { - fbdo->closeSession(); - fbdo->setSecure(); - } - - fcm_begin(fbdo, mode); + fcm_connect(fbdo, mode); fbdo->_ss.con_mode = fb_esp_con_mode_fcm; @@ -1505,6 +1534,12 @@ void FB_CM::clear() _index = 0; _tokens.clear(); std::vector().swap(_tokens); + if (_ut) + delete _ut; + if (_cfg) + delete _cfg; + if (_auth) + delete _auth; } #endif \ No newline at end of file diff --git a/src/message/FCM.h b/src/message/FCM.h index bd7a3ed61..2d67ff3fd 100644 --- a/src/message/FCM.h +++ b/src/message/FCM.h @@ -1,9 +1,9 @@ /** - * Google's Firebase Cloud Messaging class, FCM.h version 1.0.2 + * Google's Firebase Cloud Messaging class, FCM.h version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -152,12 +152,13 @@ class FB_CM String payload(FirebaseData *fbdo); private: - bool init(); + bool init(bool clearInt= false); void begin(UtilsClass *u); bool handleFCMRequest(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode, std::string &payload); bool waitResponse(FirebaseData *fbdo); bool handleResponse(FirebaseData *fbdo); - void fcm_begin(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode); + void rescon(FirebaseData *fbdo, const char *host); + void fcm_connect(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode); bool fcm_send(FirebaseData *fbdo, fb_esp_fcm_msg_mode mode, std::string &msg); void fcm_prepareHeader(std::string &header, fb_esp_fcm_msg_mode mode, std::string &payload); void fcm_prepareLegacyPayload(std::string &buf, FCM_Legacy_HTTP_Message *msg); @@ -166,7 +167,9 @@ class FB_CM void fcm_preparAPNsRegistPayload(std::string &buf, const char *application, bool sandbox, const char *APNs[], size_t numToken); void clear(); - + FirebaseConfig *_cfg = nullptr; + FirebaseAuth *_auth = nullptr; + UtilsClass *_ut = nullptr; std::string _topic = ""; std::string _server_key = ""; std::string _token = ""; diff --git a/src/rtdb/FB_RTDB.cpp b/src/rtdb/FB_RTDB.cpp index 8524ac8f0..d7d055fa8 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.0.2 + * Google's Firebase Realtime Database class, FB_RTDB.cpp version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -2221,7 +2221,7 @@ bool FB_RTDB::handleStreamRead(FirebaseData *fbdo) //trying to reconnect the stream when required at some interval as running in the loop if (millis() - STREAM_RECONNECT_INTERVAL > fbdo->_ss.rtdb.stream_resume_millis) { - reconnectStream = (fbdo->_ss.rtdb.data_tmo && !fbdo->_ss.connected) || fbdo->_ss.con_mode == fb_esp_con_mode_fcm || fbdo->_ss.con_mode == fb_esp_con_mode_storage; + reconnectStream = (fbdo->_ss.rtdb.data_tmo && !fbdo->_ss.connected) || fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream; if (fbdo->_ss.rtdb.data_tmo) fbdo->closeSession(); @@ -2277,13 +2277,7 @@ bool FB_RTDB::handleStreamRead(FirebaseData *fbdo) } if (!waitResponse(fbdo)) - { - fbdo->_ss.rtdb.data_tmo = true; - if (!fbdo->_ss.connected) //not connected in fcm shared object usage - return true; - else - return ret; - } + return ret; return true; } @@ -3285,6 +3279,33 @@ void FB_RTDB::allowMultipleRequests(bool enable) } #endif +void FB_RTDB::rescon(FirebaseData *fbdo, const char *host, fb_esp_rtdb_request_info_t *req) +{ + if (req->method == fb_esp_method::m_stream) + { + if (req->path != fbdo->_ss.rtdb.stream_path) + fbdo->_ss.rtdb.stream_path_changed = true; + else + fbdo->_ss.rtdb.stream_path_changed = false; + } + + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.rtdb.stream_path_changed || (req->method == fb_esp_method::m_stream && fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream) || (req->method != fb_esp_method::m_stream && fbdo->_ss.con_mode == fb_esp_con_mode_rtdb_stream) || strcmp(host, fbdo->_ss.host.c_str()) != 0) + { + fbdo->_ss.last_conn_ms = millis(); + fbdo->closeSession(); + fbdo->setSecure(); + } + + fbdo->_ss.host = host; + if (req->method == fb_esp_method::m_stream) + fbdo->_ss.con_mode = fb_esp_con_mode_rtdb_stream; + else + fbdo->_ss.con_mode = fb_esp_con_mode_rtdb; + + if (fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream) + fbdo->_ss.rtdb.stream_resume_millis = 0; +} + bool FB_RTDB::handleRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t *req) { fbdo->_ss.error.clear(); @@ -3315,15 +3336,10 @@ bool FB_RTDB::handleRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_ fbdo->_ss.rtdb.priority = req->priority; fbdo->_ss.rtdb.storage_type = req->storageType; - if (req->method != fb_esp_method::m_stream) - if (!fbdo->_ss.rtdb.keep_alive) - fbdo->closeSession(); - fbdo->_ss.rtdb.redirect_url.clear(); fbdo->_ss.rtdb.req_method = req->method; fbdo->_ss.rtdb.req_data_type = req->dataType; fbdo->_ss.rtdb.data_mismatch = false; - int ret = sendRequest(fbdo, req); if (ret == 0) { @@ -3422,18 +3438,10 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * std::string payloadBuf = ""; std::string header = ""; + rescon(fbdo, Signer.getCfg()->host.c_str(), req); + if (req->method == fb_esp_method::m_stream) { - //stream path change? reset the current (keep alive) connection - if (req->path != fbdo->_ss.rtdb.stream_path) - fbdo->_ss.rtdb.stream_path_changed = true; - - if (fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream || fbdo->_ss.rtdb.stream_path_changed || fbdo->_ss.con_mode == fb_esp_con_mode_fcm) - fbdo->closeSession(); - - if (fbdo->_ss.con_mode == fb_esp_con_mode_fcm || fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream) - fbdo->setSecure(); - fbdo->_ss.rtdb.stream_path.clear(); if (req->path.length() > 0) @@ -3441,21 +3449,9 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * ut->appendP(fbdo->_ss.rtdb.stream_path, fb_esp_pgm_str_1, true); fbdo->_ss.rtdb.stream_path += req->path; - fbdo->_ss.con_mode = fb_esp_con_mode_rtdb_stream; } else { - //last requested req->method was stream or fcm?, close the connection - if (fbdo->_ss.con_mode == fb_esp_con_mode_rtdb_stream || fbdo->_ss.con_mode == fb_esp_con_mode_fcm) - fbdo->closeSession(); - - if (!fbdo->_ss.connected || fbdo->_ss.con_mode == fb_esp_con_mode_fcm || fbdo->_ss.con_mode != fb_esp_con_mode_rtdb) - { - fbdo->setSecure(); - } - - fbdo->_ss.con_mode = fb_esp_con_mode_rtdb; - fbdo->_ss.rtdb.path.clear(); fbdo->_ss.rtdb.resp_etag.clear(); @@ -3802,9 +3798,6 @@ bool FB_RTDB::handleResponse(FirebaseData *fbdo) fbdo->_ss.chunked_encoding = false; fbdo->_ss.buffer_ovf = false; - if (fbdo->_ss.con_mode == fb_esp_con_mode_fcm) - defaultChunkSize = 768; - if (fbdo->_ss.con_mode != fb_esp_con_mode_rtdb_stream) { while (fbdo->httpClient.connected() && chunkBufSize <= 0) @@ -3939,9 +3932,9 @@ bool FB_RTDB::handleResponse(FirebaseData *fbdo) } if (ut->stringCompare(response.connection.c_str(), 0, fb_esp_pgm_str_11)) - fbdo->_ss.rtdb.keep_alive = true; + fbdo->_ss.rtdb.http_resp_conn_type = fb_esp_http_connection_type_keep_alive; else - fbdo->_ss.rtdb.keep_alive = false; + fbdo->_ss.rtdb.http_resp_conn_type = fb_esp_http_connection_type_close; fbdo->_ss.chunked_encoding = response.isChunkedEnc; @@ -4013,7 +4006,7 @@ bool FB_RTDB::handleResponse(FirebaseData *fbdo) } } - if (!fbdo->_ss.rtdb.data_tmo && fbdo->_ss.con_mode != fb_esp_con_mode_fcm && !fbdo->_ss.buffer_ovf) + if (!fbdo->_ss.rtdb.data_tmo && !fbdo->_ss.buffer_ovf) { //try to parse the payload for stream event data if (response.dataType == 0 || (response.isEvent && !response.hasEventData)) @@ -4132,7 +4125,7 @@ bool FB_RTDB::handleResponse(FirebaseData *fbdo) if (hstate == 1) ut->delS(header); - if (!fbdo->_ss.rtdb.data_tmo && fbdo->_ss.con_mode != fb_esp_con_mode_fcm && !fbdo->_ss.buffer_ovf) + if (!fbdo->_ss.rtdb.data_tmo && !fbdo->_ss.buffer_ovf) { //parse the payload @@ -4313,13 +4306,8 @@ bool FB_RTDB::handleResponse(FirebaseData *fbdo) fbdo->_ss.rtdb.data_millis = millis(); fbdo->_ss.rtdb.data_tmo = false; } - else if (fbdo->_ss.con_mode != fb_esp_con_mode_fcm) - { + else ut->closeFileHandle(fbdo->_ss.rtdb.storage_type == mem_storage_type_sd); - } - - if (fbdo->_ss.con_mode == fb_esp_con_mode_fcm && payload) - fbdo->_ss.rtdb.data = payload; if (pstate == 1) ut->delS(payload); @@ -4652,15 +4640,18 @@ void FB_RTDB::prepareHeader(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_ if (req->method == fb_esp_method::m_stream) { + fbdo->_ss.rtdb.http_req_conn_type = fb_esp_http_connection_type_keep_alive; ut->appendP(header, fb_esp_pgm_str_34); ut->appendP(header, fb_esp_pgm_str_35); } else if (req->method == fb_esp_method::m_download || req->method == fb_esp_method::m_restore) { + fbdo->_ss.rtdb.http_req_conn_type = fb_esp_http_connection_type_close; ut->appendP(header, fb_esp_pgm_str_34); } else { + fbdo->_ss.rtdb.http_req_conn_type = fb_esp_http_connection_type_keep_alive; ut->appendP(header, fb_esp_pgm_str_36); ut->appendP(header, fb_esp_pgm_str_37); } diff --git a/src/rtdb/FB_RTDB.h b/src/rtdb/FB_RTDB.h index d1b4cd35d..03e95af77 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.0.2 + * Google's Firebase Realtime Database class, FB_RTDB.h version 1.0.3 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -1517,6 +1517,7 @@ class FB_RTDB private: UtilsClass *ut = nullptr; void begin(UtilsClass *u); + void rescon(FirebaseData *fbdo, const char *host, fb_esp_rtdb_request_info_t *req); void clearDataStatus(FirebaseData *fbdo); bool handleRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t *req); int sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t *req); diff --git a/src/session/FB_Session.cpp b/src/session/FB_Session.cpp index a6da973a8..18af31385 100644 --- a/src/session/FB_Session.cpp +++ b/src/session/FB_Session.cpp @@ -1,9 +1,9 @@ /** - * Google's Firebase Data class, FB_Session.cpp version 1.0.1 + * Google's Firebase Data class, FB_Session.cpp version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 12, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -421,6 +421,8 @@ bool FirebaseData::httpConnected() bool FirebaseData::streamTimeout() { + if (_ss.rtdb.stream_stop) + return false; if (millis() - STREAM_ERROR_NOTIFIED_INTERVAL > _ss.rtdb.stream_tmo_Millis || _ss.rtdb.stream_tmo_Millis == 0) { _ss.rtdb.stream_tmo_Millis = millis(); @@ -438,7 +440,7 @@ bool FirebaseData::dataAvailable() bool FirebaseData::streamAvailable() { - bool ret = _ss.connected && _ss.rtdb.data_available && _ss.rtdb.stream_data_changed; + bool ret = _ss.connected && !_ss.rtdb.stream_stop && _ss.rtdb.data_available && _ss.rtdb.stream_data_changed; _ss.rtdb.data_available = false; _ss.rtdb.stream_data_changed = false; return ret; @@ -559,12 +561,16 @@ int FirebaseData::httpCode() void FirebaseData::closeSession() { - //close the socket and free the resources used by the BearSSL data - if (_ss.connected || httpClient.stream()) + if (WiFi.status() == WL_CONNECTED) { - Signer.getCfg()->_int.fb_last_reconnect_millis = millis(); - if (httpClient.stream()->connected()) - httpClient.stream()->stop(); + //close the socket and free the resources used by the BearSSL data + if (_ss.connected || httpClient.stream()) + { + Signer.getCfg()->_int.fb_last_reconnect_millis = millis(); + if (httpClient.stream()) + if (httpClient.stream()->connected()) + httpClient.stream()->stop(); + } } if (_ss.con_mode == fb_esp_con_mode_rtdb_stream) diff --git a/src/session/FB_Session.h b/src/session/FB_Session.h index a628a737a..67371246f 100644 --- a/src/session/FB_Session.h +++ b/src/session/FB_Session.h @@ -1,9 +1,9 @@ /** - * Google's Firebase Data class, FB_Session.h version 1.0.1 + * Google's Firebase Data class, FB_Session.h version 1.0.2 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 12, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) diff --git a/src/signer/Signer.cpp b/src/signer/Signer.cpp index bb77e2484..214e276fe 100644 --- a/src/signer/Signer.cpp +++ b/src/signer/Signer.cpp @@ -870,7 +870,21 @@ bool Firebase_Signer::createJWT() s += buri; ut->appendP(s, fb_esp_pgm_str_451); - tmp = ut->strP(fb_esp_pgm_str_220); + if (config->signer.tokens.scope.length() > 0) + { + std::vector scopes = std::vector(); + ut->splitTk(config->signer.tokens.scope, scopes, ","); + for (size_t i = 0; i < scopes.size(); i++) + { + ut->appendP(s, fb_esp_pgm_str_6); + s += scopes[i]; + scopes[i].clear(); + std::string().swap(scopes[i]); + } + scopes.clear(); + } + + tmp = ut->strP(fb_esp_pgm_str_220); config->signer.json->add(tmp, s.c_str()); ut->delS(tmp); } diff --git a/src/storage/FCS.cpp b/src/storage/FCS.cpp index eba5026dc..4d5eb88f0 100644 --- a/src/storage/FCS.cpp +++ b/src/storage/FCS.cpp @@ -1,9 +1,9 @@ /** - * Google's Firebase Cloud Storage class, FCS.cpp version 1.0.4 + * Google's Firebase Cloud Storage class, FCS.cpp version 1.0.5 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -168,12 +168,13 @@ bool FB_CloudStorage::listFiles(FirebaseData *fbdo, const char *bucketID) void FB_CloudStorage::rescon(FirebaseData *fbdo, const char *host) { - if (!fbdo->_ss.connected || fbdo->_ss.con_mode != fb_esp_con_mode_storage || strcmp(host, _host.c_str()) != 0) + if (!fbdo->_ss.connected || millis() - fbdo->_ss.last_conn_ms > fbdo->_ss.conn_timeout || fbdo->_ss.con_mode != fb_esp_con_mode_storage || strcmp(host, fbdo->_ss.host.c_str()) != 0) { + fbdo->_ss.last_conn_ms = millis(); fbdo->closeSession(); fbdo->setSecure(); } - _host = host; + fbdo->_ss.host = host; fbdo->_ss.con_mode = fb_esp_con_mode_storage; } @@ -251,7 +252,7 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; return false; } - + if (!FLASH_FS.exists(req->localFileName.c_str())) { fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; @@ -346,6 +347,7 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ if (ret == 0) { + fbdo->_ss.connected = true; if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_fcs_request_type_upload) { int available = Signer.getCfg()->_int.fb_file.available(); @@ -386,6 +388,7 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ } ret = handleResponse(fbdo); + fbdo->closeSession(); if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_fcs_request_type_download) Signer.getCfg()->_int.fb_file.close(); @@ -393,6 +396,8 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ Signer.getCfg()->_int.fb_processing = false; return ret; } + else + fbdo->_ss.connected = false; if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_fcs_request_type_download) Signer.getCfg()->_int.fb_file.close(); @@ -620,7 +625,6 @@ bool FB_CloudStorage::handleResponse(FirebaseData *fbdo) part1.clear(); } } - } } diff --git a/src/storage/FCS.h b/src/storage/FCS.h index f1e756d64..fc9159bd9 100644 --- a/src/storage/FCS.h +++ b/src/storage/FCS.h @@ -1,9 +1,9 @@ /** - * Google's Firebase Cloud Storage class, FCS.h version 1.0.4 + * Google's Firebase Cloud Storage class, FCS.h version 1.0.5 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 18, 2021 + * Created February 21, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -131,7 +131,6 @@ class FB_CloudStorage private: UtilsClass *ut = nullptr; - std::string _host = ""; void begin(UtilsClass *u); bool sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_t *req); void rescon(FirebaseData *fbdo, const char *host);