Realtime database class
class RealtimeDatabase
-
Create new RealtimeDatabase instance with defined url.
RealtimeDatabase Database("xxxxxxxxx.firebasedatabase.app");
RealtimeDatabase(const String &url = "")
Params:
url
- The database url
-
Class destructor
~RealtimeDatabase()
-
Assignment operator.
RealtimeDatabase &operator=(RealtimeDatabase &rhs)
Params:
rhs
- The object to be assigned to self instance
Returns:
RealtimeDatabase
reference to self instance
-
Set the Firebase database URL
Database.url("xxxxxxxxx.firebasedatabase.app");
void url(const String &url)
Params:
url
- The Firebase database URL.
-
Unbind or remove FirebaseApp.
void resetApp()
-
Get value at the node path.
The DatabaseOptions related to the Conditional Requests and Query Parameters supported by Firebase Realtime Database REST API are following.
readTimeout
, the timeout (number) in ms which limits how long the read takes on the server side. If a read request doesn't finish within the allotted time, it terminates with an HTTP 400 error. The default value is 15 min or 900,000 ms.writeSizeLimit
, the size of a write limit can be "tiny", "small", "meduim", "large" and "unlimited". To limit the size of a write, you can specify the writeSizeLimit query parameter as tiny (target=1s), small (target=10s), medium (target=30s), large (target=60s). Realtime Database estimates the size of each write request and aborts requests that will take longer than the target time.shallow
, the option (boolean) for shallowing (truncating) the JSON object data into true while JSON primitive values (string, number and boolean) will not shallow.This option cannot be mixed with any other options.
silent
, the option (boolean) to mute the return reponse payload.classicRequest
, the option (boolean) to use HTTP POST for PUT (set) and DELETE (remove).Filter
, the options for complex data filtering which included the properties i.e., orderBy, startAt, endAt,limitToFirst
, limitToLast, and equalTo.DatabaseOptions options; options.readTimeout = 5000; Database.get(aClient, "/path/to/data", options);
T get(AsyncClientClass &aClient, const String &path, DatabaseOptions &options)
Params:
aClient
- The async client.path
- The node path to get value.options
- The database options (DatabaseOptions).
Returns:
T
- The value of type T that casts from response payload.
-
Get value at the node path.
This function has only async version.
// Non-Stream Database.get(aClient, "/path/to/data", aResult); // Since v1.2.1, in SSE mode (HTTP Streaming) task, you can filter the Stream events by using RealtimeDatabase::setSSEFilters(<keywords>), // which the <keywords> is the comma separated events. // The event keywords supported are: // get - To allow the http get response (first put event since stream connected). // put - To allow the put event. // patch - To allow the patch event. // keep-alive - To allow the keep-alive event. // cancel - To allow the cancel event. // auth_revoked - To allow the auth_revoked event. // To clear all prevousely set filter to allow all Stream events, use RealtimeDatabase::setSSEFilters(). Database.setSSEFilters("get,put,patch,keep-alive,cancel,auth_revoked"); Database.get(aClient, "/path/to/stream/data", aResult, true /* SSE mode (HTTP Streaming) */);
void get(AsyncClientClass &aClient, const String &path, AsyncResult &aResult, bool sse = false)
Params:
aClient
- The async client.path
- The node path to get value.aResult
- The async result (AsyncResult)sse
- The Server-sent events (Stream) mode
-
🔹 void get(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, bool sse = false, const String &uid = "")
Get value at the node path.
This function has only async version.
// Non-Stream Database.get(aClient, "/path/to/data", cb); // Since v1.2.1, in SSE mode (HTTP Streaming) task, you can filter the Stream events by using RealtimeDatabase::setSSEFilters(<keywords>), // which the <keywords> is the comma separated events. // The event keywords supported are: // get - To allow the http get response (first put event since stream connected). // put - To allow the put event. // patch - To allow the patch event. // keep-alive - To allow the keep-alive event. // cancel - To allow the cancel event. // auth_revoked - To allow the auth_revoked event. // To clear all prevousely set filter to allow all Stream events, use RealtimeDatabase::setSSEFilters(). Database.setSSEFilters("get,put,patch,keep-alive,cancel,auth_revoked"); Database.get(aClient, "/path/to/stream/data", cb, true /* SSE mode (HTTP Streaming) */);
void get(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, bool sse = false, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to get value.cb
- The async result callback (AsyncResultCallback).sse
- The Server-sent events (Stream) mode.uid
- The user specified UID of async result (optional).
-
🔹 void get(AsyncClientClass &aClient, const String &path, DatabaseOptions &options, AsyncResult &aResult)
Get value at the node path.
// Filtering data. DatabaseOptions options; options.filter.orderBy("Data"); options.filter.startAt(105); options.filter.endAt(120); options.filter.limitToLast(8); Database.get<String>(aClient, "/path/to/data", options, aResult);
void get(AsyncClientClass &aClient, const String &path, DatabaseOptions &options, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to get value.options
- The database options (DatabaseOptions).aResult
- The async result (AsyncResult)
-
🔹 void get(AsyncClientClass &aClient, const String &path, DatabaseOptions &options, AsyncResultCallback cb, const String &uid = "")
Get value at the node path.
// Filtering data. DatabaseOptions options; options.filter.orderBy("Data"); options.filter.startAt(105); options.filter.endAt(120); options.filter.limitToLast(8); Database.get<String>(aClient, "/path/to/data", options, cb);
void get(AsyncClientClass &aClient, const String &path, DatabaseOptions &options, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to get value.options
- The database options (DatabaseOptions).cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
🔹 void get(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Get value at the node path. The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.get(aClient, "/path/to/data", getFile(fileConfig), aResult);
void get(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to get value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.aResult
- The async result (AsyncResult)
-
🔹 void get(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Get value at the node path. The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.get(aClient, "/path/to/data", getFile(fileConfig), cb);
void get(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to get value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Check if data exists in database.
This function has only sync version.
// Check if the data exists in database. bool status = Database.existed(aClient, "/path/to/data"); // The status will be true if data exists or returns false if data does not exist or error. // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
bool existed(AsyncClientClass &aClient, const String &path)
Params:
aClient
- The async client.path
- The node path to check.
Returns:
- boolean value indicates the operating status.
-
Perform OTA update using a firmware file from the database.
The data of node to download should be base64 encoded string of the firmware file.
Database.ota(aClient, "/path/to/data", aResult);
void ota(AsyncClientClass &aClient, const String &path, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to download.aResult
- The async result (AsyncResult)
-
🔹 void ota(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, const String &uid = "")
Perform OTA update using a firmware file from the database.
The data of node to download should be base64 encoded string of the firmware file.
Database.ota(aClient, "/path/to/data", cb);
void ota(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to download.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Set value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Set float value with 3 decimal places limit. bool status = Database.set<number_t>(aClient, "/path/to/data", number_t(123.456789, 3)); // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
bool set(AsyncClientClass &aClient, const String &path, T value)
Params:
aClient
- The async client.path
- The node path to set the value.value
- The value to set.
Returns:
- boolean value indicates the operating status.
-
Set value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Set float value with 3 decimal places limit. Database.set<number_t>(aClient, "/path/to/data", number_t(123.456789, 3), aResult);
void set(AsyncClientClass &aClient, const String &path, T value, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to set the value.value
- The value to set.aResult
- The async result (AsyncResult)
-
🔹 void set(AsyncClientClass &aClient, const String &path, T value, AsyncResultCallback cb, const String &uid = "")
Set value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Set float value with 3 decimal places limit. Database.set<number_t>(aClient, "/path/to/data", number_t(123.456789, 3), cb);
void set(AsyncClientClass &aClient, const String &path, T value, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to set the value.value
- The value to set.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
🔹 void set(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Set content from file to database. The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.set(aClient, "/path/to/data", getFile(fileConfig), aResult);
void set(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to set value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.aResult
- The async result (AsyncResult)
-
🔹 void set(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Set content from file to database. The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.set(aClient, "/path/to/data", getFile(fileConfig), cb);
void set(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to get value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Push value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Push float value with 3 decimal places limit. String name = Database.push<number_t>(aClient, "/path/to/data", number_t(123.456789, 3)); // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
String push(AsyncClientClass &aClient, const String &path, T value)
Params:
aClient
- The async client.path
- The node path to push the value.value
- The value to push.
Returns:
- String random uuid string of a new node that created.
-
Push value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Push float value with 3 decimal places limit. void name = Database.push<number_t>(aClient, "/path/to/data", number_t(123.456789, 3), aResult); // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
void push(AsyncClientClass &aClient, const String &path, T value, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to push the value.value
- The value to push.aResult
- The async result (AsyncResult).
-
🔹 void push(AsyncClientClass &aClient, const String &path, T value, AsyncResultCallback cb, const String &uid = "")
Push value to database.
The value type can be primitive types, Arduino
String
,string_t
,number_t
,boolean_t
andobject_t
.The
string_t
is for string placeholder e.g.string_t("hello there")
. Thenumber_t
is for number (integer, float, double) placeholder with decimal places e.g.number_t(123.45678, 2)
. Theboolean_t
is for boolean placeholder e.g.boolean_t(true)
. Theobject_t
is for JSON and JSON Array objects placeholder e.g.object_t("{\"name\":\"Jack\"}")
orobject_t("[123,true,\"hello\"]")
.// Push float value with 3 decimal places limit. Database.push<number_t>(aClient, "/path/to/data", number_t(123.456789, 3), cb);
void push(AsyncClientClass &aClient, const String &path, T value, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to push the value.value
- The value to push.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
🔹 void push(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Push content from file to database.
The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.set(aClient, "/path/to/data", getFile(fileConfig), aResult);
void push(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to get value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.aResult
- The async result (AsyncResult)
-
🔹 void push(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Push content from file to database.
The FileConfig object constructor should be included filename and FileConfigCallback.
The FileConfigCallback function contains the parameters i.e., File reference returned from file operation, filename for file operation and file_operating_mode.
#include <FS.h> File myFile; // Define the File object globally. void fileCallback(File &file, const char *filename, file_operating_mode mode) { switch (mode) { case file_mode_open_read: myFile = SPIFFS.open(filename, "r"); break; case file_mode_open_write: myFile = SPIFFS.open(filename, "w"); break; case file_mode_open_append: myFile = SPIFFS.open(filename, "a"); break; case file_mode_remove: SPIFFS.remove(filename); break; default: break; } // Set the internal FS object with global File object. file = myFile; } FileConfig fileConfig("/example.txt", fileCallback); Database.set(aClient, "/path/to/data", getFile(fileConfig), cb);
void push(AsyncClientClass &aClient, const String &path, file_config_data &file, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to get value.file
- The filesystem data (file_config_data) obtained from FileConfig class object.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Update (patch) JSON object to database.
bool status = Database.update<object_t>(aClient, "/path/to/data", object_t("{\"name\":\"Jack\"}")); // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
bool update(AsyncClientClass &aClient, const String &path, const T &value)
Params:
aClient
- The async client.path
- The node path to update.value
- The JSON object (object_t) to update.
Returns:
- boolean value indicates the operating status.
-
Update (patch) JSON object to database.
Database.update<object_t>(aClient, "/path/to/data", object_t("{\"name\":\"Jack\"}"), aResult);
void update(AsyncClientClass &aClient, const String &path, const T &value, AsyncResult &aResult)
Params:
aClient
- The async client.path
- The node path to update.value
- The JSON object (object_t) to update.aResult
- The async result (AsyncResult).
-
🔹 void update(AsyncClientClass &aClient, const String &path, const T &value, AsyncResultCallback cb, const String &uid = "")
Update (patch) JSON object to database.
Database.update<object_t>(aClient, "/path/to/data", object_t("{\"name\":\"Jack\"}"), cb);
void update(AsyncClientClass &aClient, const String &path, const T &value, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to update.value
- The JSON object (object_t) to update.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Remove node from database
bool status = Database.remove(aClient, "/path/to/data"); // To check the operation status and error information in case of error after the task was done. if (aClient.lastError().code() == 0) Serial.println("Operation is success."); else Firebase.printf("Error, msg: %s, code: %d\n", aClient.lastError().message().c_str(), aClient.lastError().code());
bool remove(AsyncClientClass &aClient, const String &path)
Params:
aClient
- The async client.path
- The node path to remove.
Returns:
- boolean value indicates the operating status.
-
Remove node from database
Database.remove(aClient, "/path/to/data", aResult);
void remove(AsyncClientClass &aClient, const String &path, AsyncResult &aResult)
Params:
aClient
- The async clientpath
- The node path to remove.aResult
- The async result (AsyncResult).
-
🔹 void remove(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, const String &uid = "")
Remove node from database
Database.remove(aClient, "/path/to/data", cb);
void remove(AsyncClientClass &aClient, const String &path, AsyncResultCallback cb, const String &uid = "")
Params:
aClient
- The async client.path
- The node path to remove.cb
- The async result callback (AsyncResultCallback).uid
- The user specified UID of async result (optional).
-
Filtering response payload for SSE mode (HTTP Streaming).
This function is available since v1.2.1.
This is optional to allow specific events filtering.
The following event keywords are supported.
get
- To allow the http get response (first put event since stream connected).put
- To allow the put event.patch
- To allow the patch event.keep-alive
- To allow the keep-alive event.cancel
- To allow the cancel event.auth_revoked
- To allow the auth_revoked event.You can separate each keyword with comma or space.
To clear all prevousely set filter to allow all Stream events, use
RealtimeDatabase::setSSEFilters()
.// To all all tream events. Database.setSSEFilters("get,put,patch,keep-alive,cancel,auth_revoked"); // SSE mode (HTTP Streaming) Database.get(aClient, "/path/to/stream/data", cb, true);
void setSSEFilters(const String &filter = "")
Params:
filter
- The event keywords for filtering.
-
Set Arduino OTA Storage.
void setOTAStorage(OTAStorage &storage)
Params:
storage
- The ArduinoOTAStorage
class object.
-
Perform the async task repeatedly. Should be places in main loop function.
void loop()