mobizt / Firebase-ESP32

[DEPRECATED]🔥 Firebase RTDB Arduino Library for ESP32. The complete, fast, secured and reliable Firebase Arduino client library that supports CRUD (create, read, update, delete) and Stream operations.
MIT License
415 stars 118 forks source link

Possible BUG, Data Mismatch but still provides data #114

Closed Keegan-Cruickshank closed 3 years ago

Keegan-Cruickshank commented 3 years ago

This is a strange one. Running a task on core 0. Below is my code and in loop I am occasionally sending a push to firebase with a new lastSeen value:

void Task1( void * parameter) {
  for (;;) {
    if(firebaseSet && !sendingTimer) {
      if (!Firebase.readStream(firebaseData)){
        Serial.print("Read stream error: ");
        Serial.println(firebaseData.errorReason());
        Serial.println();
      }

      if (firebaseData.streamTimeout()){
        Serial.println("Stream timeout");
        Serial.println();
      }

      if (firebaseData.streamAvailable()){
        Serial.print("Stream data: ");
        String type = firebaseData.dataType();
        Serial.print(type);
        Serial.print("  -  ");
        if (firebaseData.dataType() == "int")
          Serial.print(firebaseData.intData());
        else if (firebaseData.dataType() == "float")
          Serial.print(firebaseData.floatData(), 5);
        else if (firebaseData.dataType() == "double")
          printf("%.9lf", firebaseData.doubleData());
        else if (firebaseData.dataType() == "boolean")
          Serial.print(firebaseData.boolData() == 1 ? "true" : "false");
        else if (firebaseData.dataType() == "string")
          Serial.print(firebaseData.stringData());
        else if (firebaseData.dataType() == "json")
          Serial.print(firebaseData.jsonString());
        Serial.println();
      }
    }
    vTaskDelay(2000);
  }
}

My serial output shows this with the last two lines repeating indefinitely:

Stream data: json  -  {"color":{"b":150,"g":71,"r":255},"lastOnline":"1605184636","status":2}
Stream data: json  -  {"color":{"b":150,"g":71,"r":255},"lastOnline":"1605184636","status":2}
Stream timeout

Read stream error: data type mismatch

Stream data: json  -  {"color":{"b":150,"g":71,"r":255},"lastOnline":"1605184859","status":2}
Read stream error: data type mismatch

Stream data: json  -  {"color":{"b":150,"g":71,"r":255},"lastOnline":"1605184859","status":2}
Read stream error: data type mismatch

Stream data: json  -  {"color":{"b":150,"g":71,"r":255},"lastOnline":"1605184859","status":2}

Where I push the lastSeen value I have a delay in the sendingTimer variable that is true for 3s before and 3s after the sendingTimer is active. Do you know why it is saying mismatch and then providing the json values anyway?

mobizt commented 3 years ago

It's not a bug. It's the desired behavior to keep the last success operation payload data.

If the current operation failed, the payload data should not be changed.

Keegan-Cruickshank commented 3 years ago

I understand now thanks. What is "data type mismatch" then.

mobizt commented 3 years ago

When you create the separate RTOS task for stream. The library can't access to your stream task recourses as normally. The uncontrolled condition may be occurred.

This issue also described in the stream task examples of a years ago of obsoleted version and the usage like this is not recommended.

Use the stream callback or run the read stream on the main task which called by loop instead.

Keegan-Cruickshank commented 3 years ago

Thanks I'll give it a go

mobizt commented 3 years ago

In the stream callback or loop, if you get this data type mismatch again please let me know.

Keegan-Cruickshank commented 3 years ago

When I have the streamCallback enabled instead I get this immediately after a firebase command to update a value:

[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
Firebase Timeout
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
[E][fb_ssl_client32.cpp:69] start_ssl_client(): ERROR opening socket
[E][FB_WCS32.cpp:160] connect(): start_ssl_client: -1
mobizt commented 3 years ago

The code for begin the stream ever called?

Look like it's never initiated.

Keegan-Cruickshank commented 3 years ago

Yes but do I need to call again after a Firebase.set() is run? Code works until Firebase.set() runs then those error show

mobizt commented 3 years ago

You can't use the same Firebase Data object for stream in the callback mode and normal Firebase calls.

It's because, that Firebase Data object is belong to the internal stream tasks already and any firebase calls which access to this Firebase Data object will interrupt the stream task and some unhandled behavior my occur (wdt reset or anything)

If you want this for saving the memory usage by using only one Firebase Data object, please check the stream loop example.

Keegan-Cruickshank commented 3 years ago

Thats fine I have spare memory. Did not even think of this. Appreciate it. All fixed. Keep up the good work. Great library.

mobizt commented 3 years ago

If you're using the library, version older than 3.8.9, when the payload or stream data is bigger than 512 bytes, the wdt reset may occur.

Please update the library to latest version which you can limit the payload response size with setResponseSize method of Firebase Data object as in ESP8266.

Note that, when the payload data or stream data is JSON which its size is bigger than set in the setResponseSize, the JSON payload can't parse due to truncated data and you will get the empty FirebaseJson object instead.

mobizt commented 3 years ago

@vanminh1310

Because data from the node "auto_man" is not number. It may not existed or its type can be string, boolean, JSON or JSON Array. When you call getInt from that node, it will return error like that.

If you're not sure the type of data at that node, please use get and check the dataType later.

Ex.


if(Firebase.get(firebaseData, "auto_man"))
{
  if(firebaseData.dataType() == "int")
  {

  }
  else if(firebaseData.dataType() == "string")
  {

  }
  else if(firebaseData.dataType() == "boolean")
  {

  }
}

Check this for the dataType.

vanminh1310 commented 3 years ago

Thank you so much my problem was solved