Skip to content

Commit

Permalink
Prevent auth task handler from running when downloading/uploading file
Browse files Browse the repository at this point in the history
  • Loading branch information
mobizt committed Jun 26, 2024
1 parent 0ef522b commit fffcc2d
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 45 deletions.
18 changes: 9 additions & 9 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

Revision `2024-06-11T01:14:40Z`
Revision `2024-06-26T07:53:25Z`

# Async Firebase Client library for Arduino Frequently Asked Questions.

## Table of Contents

- [Q1: Why I get an error `"TCP connection failed"`?](#q1-why-i-get-an-error-tcp-connection-failed)
- [Q2: Why I get an error `"TCP send failed"`?](#q1-why-i-get-an-error-tcp-connection-failed)
- [Q3: Why I get an error `"TCP receive time out"`?](#q3-why-i-get-an-error-tcp-receive-time-out)
- [Q3: Why I get an error `"TCP receive timed out"`?](#q3-why-i-get-an-error-tcp-receive-time-out)
- [Q4: Why I get an error `"TCP disconnected"`?](#q4-why-i-get-an-error-tcp-disconnected)
- [Q5: What should I do when I get the error `"error opening file"`?](#q5-what-should-i-do-when-i-get-the-error-error-opening-file)
- [Q6: What should I do when I get the error `"error reading file"` or `"error writng file"`?](#q6-what-should-i-do-when-i-get-the-error-error-reading-file-or-error-writng-file)
Expand All @@ -17,12 +17,12 @@ Revision `2024-06-11T01:14:40Z`
- [Q10: What should I do when I get the error `"JWT, token signing fail"`?](#q10-what-should-i-do-when-i-get-the-error-jwt-token-signing-fail)
- [Q11: What should I do when I get the error `"too low sketch space"`?](#q11-what-should-i-do-when-i-get-the-error-too-low-sketch-space)
- [Q12: What should I do when I get the error `"firmware write failed"` or `"firmware end failed"`?](#q12-what-should-i-do-when-i-get-the-error-firmware-write-failed-or-firmware-end-failed)
- [Q13: What should I do when I get the error `"stream time out"`?](#q13-what-should-i-do-when-i-get-the-error-stream-time-out)
- [Q13: What should I do when I get the error `"stream connection timed out"`?](#q13-what-should-i-do-when-i-get-the-error-stream-connection-timed-out)
- [Q14: What should I do when I get the error `"auth revoked"`?](#q14-what-should-i-do-when-i-get-the-error-auth-revoked)
- [Q15: Why I get the error `"app was not assigned"`?](#q15-why-i-get-the-error-app-was-not-assigned)
- [Q16: Why I get the error `"operation was cancelled"`?](#q16-why-i-get-the-error-operation-was-cancelled)
- [Q17: Why I get the error `"JWT, time was not set or not valid"`?](#q17-why-i-get-the-error-jwt-time-was-not-set-or-not-valid)
- [Q18: Why sometimes the Reltime Database Stream does not work when WiFi was disconnected and reconnected and I get the error `"stream time out"`?](#q18-why-sometimes-the-reltime-database-stream-does-not-work-when-wifi-was-disconnected-and-reconnected-and-i-get-the-error-stream-time-out)
- [Q18: Why sometimes the Reltime Database Stream does not work when WiFi was disconnected and reconnected and I get the error `"stream connection timed out"`?](#q18-why-sometimes-the-reltime-database-stream-does-not-work-when-wifi-was-disconnected-and-reconnected-and-i-get-the-error-stream-time-out)
- [Q19: Can I use delay in this library?](#q19-can-i-use-delay-in-this-library)
- [Q20: Can I change the send timeout?](#q20-can-i-change-the-send-timeout)
- [Q21: Can I change the read timeout?](#q21-can-i-change-the-read-timeout)
Expand Down Expand Up @@ -122,7 +122,7 @@ Then there are many possible causes of connection issue that cause the SSL clien

- The send timeout is too small. In case sync task, the send timeout can be set via `AsyncClientClass::setSyncSendTimeout`. The async task send timeout is 30 seconds and cannot be changed and you have to fix the possible issues instead of increasing the send timeout.

### Q3: Why I get an error `"TCP receive time out"`?
### Q3: Why I get an error `"TCP receive timed out"`?

#### A3: The time that used while processing the server response (header or payload) is greater than the read timeout.

Expand Down Expand Up @@ -221,7 +221,7 @@ In case download process interrupted, see [Q1: Why I get an error `"TCP connecti

In case unkbown error, please verify your free flash and do not write any file to the filesytem that decreased the free flash space.

### Q13: What should I do when I get the error `"stream time out"`?
### Q13: What should I do when I get the error `"stream connection timed out"`?

#### A13: The error can be occured when no keep-alive event received during the stream timeout period.

Expand Down Expand Up @@ -259,7 +259,7 @@ When no more memory to be allocated for new task. You have to reduce the memory

The timestamp that you set in the uint32_t variable of time status callback function is not valid or it was not set.

### Q18: Why sometimes the Reltime Database Stream does not work when WiFi was disconnected and reconnected and I get the error `"stream time out"`?
### Q18: Why sometimes the Reltime Database Stream does not work when WiFi was disconnected and reconnected and I get the error `"stream connection timed out"`?

#### A18: The problem is due to the WiFi reconnection interferences.

Expand All @@ -269,7 +269,7 @@ Please read [Possible WiFi issues](#possible-wifi-issues).

#### A19: Yes, but it's not recommend.

If the delay was used in the loop it causes many errors e.g. read and send time out and stream time out.
If the delay was used in the loop it causes many errors e.g. read and send timed out and stream connection timed out.

### Q20: Can I change the send timeout?

Expand Down Expand Up @@ -306,7 +306,7 @@ The memory allocation failure due to out of memory can cause the dangling pointe

If network disconnected and re-connected, network connected but internet access was missing, and no events included keep-alive event received within 40 seconds, the Stream will be closed and restarted automatically as long as the async client's queue was running.

The `stream time out`error will show in case time out (no events received within 40 seconds).
The `stream connection timed out`error will show in case timed out (no events received within 40 seconds).

If you are intend to totally remove the steam task from the queue, and stream is running, use `AsyncClientClass::stopAsync()`. If you are not sure that stream was running or stopped because of other tasks, use `AsyncClientClass::stopAsync(true)` to cancell all tasks and remove all tasks from the queue.

Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/mobizt/FirebaseClient/.github%2Fworkflows%2Fcompile_library.yml?logo=github&label=compile) [![Github Stars](https://img.shields.io/github/stars/mobizt/FirebaseClient?logo=github)](https://github.com/mobizt/FirebaseClient/stargazers) ![Github Issues](https://img.shields.io/github/issues/mobizt/FirebaseClient?logo=github)

![GitHub Release](https://img.shields.io/github/v/release/mobizt/FirebaseClient) ![Arduino](https://img.shields.io/badge/Arduino-v1.2.17-57C207?logo=arduino) ![PlatformIO](https://badges.registry.platformio.org/packages/mobizt/library/FirebaseClient.svg) ![GitHub Release Date](https://img.shields.io/github/release-date/mobizt/FirebaseClient)
![GitHub Release](https://img.shields.io/github/v/release/mobizt/FirebaseClient) ![Arduino](https://img.shields.io/badge/Arduino-v1.2.18-57C207?logo=arduino) ![PlatformIO](https://badges.registry.platformio.org/packages/mobizt/library/FirebaseClient.svg) ![GitHub Release Date](https://img.shields.io/github/release-date/mobizt/FirebaseClient)

[![GitHub Sponsors](https://img.shields.io/github/sponsors/mobizt?logo=github)](https://github.com/sponsors/mobizt)

Revision `2024-06-25T23:50:45Z`
Revision `2024-06-26T07:53:25Z`

## Table of Contents

Expand Down Expand Up @@ -479,7 +479,7 @@ To run multiple `SSE mode (HTTP Streaming)` tasks, you have to run each task in
The async task handler will kepp the async tasks running as long as it places in the main `loop` function.

> [!IMPORTANT]
> Do not underestimate the important the async task handler location and usage. The non-async third-party library and user blocking code, `delay` function and placing the async task handler in the `millis` code blocks, will cause the async task to run slowly and the time out can of operation will be occurred. The `SSE mode (HTTP Streaming)` task will not update in realtime.
> Do not underestimate the important the async task handler location and usage. The non-async third-party library and user blocking code, `delay` function and placing the async task handler in the `millis` code blocks, will cause the async task to run slowly and the timed out will be occurred. The `SSE mode (HTTP Streaming)` task will not update in realtime.
> The async task handler i.e. `FirebaseApp::loop()`, `RealtimeDatabase::loop()`, `Storage::loop()`, `Messaging::loop()`, `CloudStorage::loop()` and `CloudFunctions` should be placed inside the main `loop` function, at the top most of the `loop`.
> [!NOTE]
Expand Down Expand Up @@ -507,7 +507,7 @@ In case using ESP8266 without `PSRAM` and you want to reduce the memory usage, y
Note that, because the receive buffer size was set to minimum safe value, 1024, the large server response may not be able to handle.

> [!WARNING]
> In ESP32, `WiFiClient` and `WiFiClientSecure` classes are unable to detect the server disconnection in case server session time out and the TCP session was kept alive for reuse in most tasks this library. The server session timed out will not happen if data was sent or received within the server time out period. The TCP session timeout in seconds in this library can be set via macro or build flag `FIREBASE_SESSION_TIMEOUT`.
> In ESP32, when using `WiFiClient` with `ESP_SSLClient` classes, `WiFiClient` was unable to detect the server disconnection in case server session timed out and the TCP session was kept alive for reuse in most tasks in this library. The TCP session timeout in seconds (equal to or greater than 150 seconds) in this library can be set via `AsyncClientClass::setSessionTimeout`.

- ### Async Client
Expand Down Expand Up @@ -2953,7 +2953,7 @@ The following options are not yet defined in [**Config.h**](src/Config.h) and ca
```cpp
FIREBASE_ETHERNET_MODULE_LIB `"EthernetLibrary.h"` // For the Ethernet library to work with external Ethernet module.
FIREBASE_ETHERNET_MODULE_CLASS EthernetClass // For the Ethernet class object of Ethernet library to work with external Ethernet module.
FIREBASE_ETHERNET_MODULE_TIMEOUT 2000 // For the time out in milliseconds to wait external Ethernet module to connect to network.
FIREBASE_ETHERNET_MODULE_TIMEOUT 2000 // For the timeout in milliseconds to wait external Ethernet module to connect to network.
ENABLE_ESP8266_ENC28J60_ETH // For native core library ENC28J60 Ethernet module support in ESP8266.
ENABLE_ESP8266_W5500_ETH // For native core library W5500 Ethernet module support in ESP8266.
ENABLE_ESP8266_W5100_ETH // For native core library W5100 Ethernet module support in ESP8266.
Expand All @@ -2963,7 +2963,6 @@ ENABLE_ASYNC_TCP_CLIENT // For Async TCP Client usage.
FIREBASE_ASYNC_QUEUE_LIMIT // For maximum async queue limit setting for an async client.
FIREBASE_PRINTF_PORT // For Firebase.printf debug port.
FIREBASE_PRINTF_BUFFER // Firebase.printf buffer size.
FIREBASE_SESSION_TIMEOUT // For TCP session timeout in seconds. The default TCP session timeout is 150 seconds
```

You can assign the optional build options using one of the following methods.
Expand All @@ -2985,7 +2984,7 @@ For external Ethernet module integation used with function `setEthernetClient`,

`FIREBASE_ETHERNET_MODULE_CLASS` is the name of static object defined from class e.g. `Ethernet`.

`FIREBASE_ETHERNET_MODULE_TIMEOUT` is the time out in milliseconds to wait network connection.
`FIREBASE_ETHERNET_MODULE_TIMEOUT` is the timeout in milliseconds to wait for network connection.

For disabling predefined options instead of editing the [**Config.h**](src/Config.h) or using `#undef` in `UserConfig.h`, you can define these build flags with these names or macros in `UserConfig.h`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ void setup()
ssl_client2.setDebugLevel(1);
ssl_client3.setDebugLevel(1);

// This timeout in seconds is required for WiFiClient used with ESP_SSLClient to limit the timeout of keep-alive TCP sesssion
// as the WiFiClient does not detect the server disconnection, WiFiClient::connected returns true and write error can be occurred.
// This timeout was not applied for Stream.
aClient1.setSessionTimeout(150);
aClient2.setSessionTimeout(150);

initializeApp(aClient3, app, getAuth(user_auth), asyncCB, "authTask");

// Binding the FirebaseApp for authentication handler.
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": "FirebaseClient",
"version": "1.2.17",
"version": "1.2.18",
"keywords": "communication, REST, esp32, esp8266, arduino",
"description": "Async Firebase Client library for Arduino.",
"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=FirebaseClient

version=1.2.17
version=1.2.18

author=Mobizt

Expand Down
21 changes: 17 additions & 4 deletions resources/docs/async_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,26 +125,39 @@ void setETag(const String &etag)
10. ## 🔹 void setSyncSendTimeout(uint32_t timeoutSec)
Set the sync task's send time out in seconds.
Set the sync task's send timeout in seconds.
```cpp
void setSyncSendTimeout(uint32_t timeoutSec)
```

**Params:**

- `timeoutSec` - The TCP write time out in seconds.
- `timeoutSec` - The TCP write timeout in seconds.


11. ## 🔹 void setSyncReadTimeout(uint32_t timeoutSec)

Set the sync task's read time out in seconds.
Set the sync task's read timeout in seconds.

```cpp
void setSyncReadTimeout(uint32_t timeoutSec)
```
**Params:**
- `timeoutSec` - The TCP read time out in seconds.
- `timeoutSec` - The TCP read timeout in seconds.
12. ## 🔹 void setSessionTimeout(uint32_t timeoutSec)
Set the TCP session timeout in seconds.
```cpp
void setSessionTimeout(uint32_t timeoutSec)
```

**Params:**

- `timeoutSec` - The TCP session timeout in seconds.

4 changes: 2 additions & 2 deletions resources/docs/realtime_database_result.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ String data()

8. ## 🔹 bool eventTimeout()

Get the SSE mode (HTTP Streaming) event time out status.
Get the SSE mode (HTTP Streaming) event timed out status.

```cpp
bool eventTimeout()
```

**Returns:**

- `bool` - The SSE mode (HTTP Streaming) event time out status.
- `bool` - The SSE mode (HTTP Streaming) event timed out status.


9. ## 🔹 realtime_database_data_type type()
Expand Down
4 changes: 0 additions & 4 deletions src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@
*
* * 🏷️ For Firebase.printf buffer size.
* #define FIREBASE_PRINTF_BUFFER 2048
*
* * 🏷️ For TCP session timeout in seconds.
* The default TCP session timeout is 150 seconds.
* #define FIREBASE_SESSION_TIMEOUT
*/

#if __has_include("UserConfig.h")
Expand Down
25 changes: 16 additions & 9 deletions src/core/AsyncClient/AsyncClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Created June 25, 2024
* Created June 26, 2024
*
* For MCU build target (CORE_ARDUINO_XXXX), see Options.h.
*
Expand Down Expand Up @@ -186,7 +186,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
uint32_t auth_ts = 0;
uint32_t cvec_addr = 0;
uint32_t result_addr = 0;
uint32_t sync_send_timeout_sec = 0, sync_read_timeout_sec = 0;
uint32_t sync_send_timeout_sec = 0, sync_read_timeout_sec = 0, session_timeout_sec = 0;
Timer session_timer;
Client *client = nullptr;
#if defined(ENABLE_ASYNC_TCP_CLIENT)
Expand Down Expand Up @@ -236,7 +236,7 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
void newCon(async_data_item_t *sData, const char *host, uint16_t port)
{

if ((!sData->sse && session_timer.remaining() == 0) || (sse && !sData->sse) || (!sse && sData->sse) || (sData->auth_used && sData->state == async_state_undefined) ||
if ((!sData->sse && session_timeout_sec >= FIREBASE_SESSION_TIMEOUT_SEC && session_timer.remaining() == 0) || (sse && !sData->sse) || (!sse && sData->sse) || (sData->auth_used && sData->state == async_state_undefined) ||
strcmp(this->host.c_str(), host) != 0 || this->port != port)
{
stop(sData);
Expand Down Expand Up @@ -1428,8 +1428,8 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
this->host = host;
this->port = port;

if (client && client->connected())
session_timer.feed(FIREBASE_SESSION_TIMEOUT);
if (client && client->connected() && session_timeout_sec >= FIREBASE_SESSION_TIMEOUT_SEC)
session_timer.feed(session_timeout_sec);

return sData->return_type;
}
Expand Down Expand Up @@ -2420,18 +2420,25 @@ class AsyncClientClass : public ResultBase, RTDBResultBase
void setETag(const String &etag) { reqEtag = etag; }

/**
* Set the sync task's send time out in seconds.
* Set the sync task's send timeout in seconds.
*
* @param timeoutSec The TCP write time out in seconds.
* @param timeoutSec The TCP write timeout in seconds.
*/
void setSyncSendTimeout(uint32_t timeoutSec) { sync_send_timeout_sec = timeoutSec; }

/**
* Set the sync task's read time out in seconds.
* Set the sync task's read timeout in seconds.
*
* @param timeoutSec The TCP read time out in seconds.
* @param timeoutSec The TCP read timeout in seconds.
*/
void setSyncReadTimeout(uint32_t timeoutSec) { sync_read_timeout_sec = timeoutSec; }

/**
* Set the TCP session timeout in seconds.
*
* @param timeoutSec The TCP session timeout in seconds.
*/
void setSessionTimeout(uint32_t timeoutSec) { session_timeout_sec = timeoutSec; }
};

#endif
2 changes: 2 additions & 0 deletions src/core/AsyncClient/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

#define FIREBASE_RECONNECTION_TIMEOUT_MSEC 5000

#define FIREBASE_SESSION_TIMEOUT_SEC 150

#define FIREBASE_AUTH_PLACEHOLDER FPSTR("<auth_token>")

#if !defined(FIREBASE_ASYNC_QUEUE_LIMIT)
Expand Down
2 changes: 1 addition & 1 deletion src/core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#undef FIREBASE_CLIENT_VERSION
#endif

#define FIREBASE_CLIENT_VERSION "1.2.17"
#define FIREBASE_CLIENT_VERSION "1.2.18"

static void sys_idle()
{
Expand Down
6 changes: 3 additions & 3 deletions src/core/Error.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Created May 5, 2024
* Created June 26, 2024
*
* The MIT License (MIT)
* Copyright (c) 2024 K. Suwatchai (Mobizt)
Expand Down Expand Up @@ -143,7 +143,7 @@ class FirebaseError
err.setError(code, FPSTR("TCP send failed"));
break;
case FIREBASE_ERROR_TCP_RECEIVE_TIMEOUT:
err.setError(code, FPSTR("TCP receive time out"));
err.setError(code, FPSTR("TCP receive timed out"));
break;
case FIREBASE_ERROR_TCP_DISCONNECTED:
err.setError(code, FPSTR("TCP disconnected"));
Expand Down Expand Up @@ -176,7 +176,7 @@ class FirebaseError
err.setError(code, FPSTR("firmware end failed"));
break;
case FIREBASE_ERROR_STREAM_TIMEOUT:
err.setError(code, FPSTR("stream time out"));
err.setError(code, FPSTR("stream connection timed out"));
break;
case FIREBASE_ERROR_STREAM_AUTH_REVOKED:
err.setError(code, FPSTR("auth revoked"));
Expand Down
4 changes: 0 additions & 4 deletions src/core/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,4 @@
#define FIREBASE_ASYNC_CLIENT AsyncClient
#endif

#if !defined(FIREBASE_SESSION_TIMEOUT)
#define FIREBASE_SESSION_TIMEOUT 150
#endif

#endif

0 comments on commit fffcc2d

Please sign in to comment.