The FirebaseDatabase item allows to read and write user-specific and public data from and to the Firebase Realtime Database. Data is synced across all clients in realtime, and remains available when your app goes offline. As soon as the user goes online again, the changes are synced up to the Firebase cloud backend. More...
Import Statement: | import Felgo 4.0 |
Inherits: |
Data inside your Firebase Realtime Database is stored as a JSON tree. Unlike a SQL database, there are no tables or records. Theoretically, the Firebase database allows nesting your data up to 32 levels deep. However, a best practice is to avoid nesting data where possible and create a data structure as flat as possible.
Here is a short example what a Firebase database looks like. It contains a public branch, with a news
item, and a users
branch, that contains a list of users. User objects have the properties
username
, age
and motto
.
Note: Check out the Firebase Plugin page for more examples!
{ "public" : { "news" : "Firebase Plugin is now live!" }, "users" : { "<user-id>" : { "username" : "John Doe", "age" : 22, "motto" : "Felgo is awesome!" } } }
Before creating the data structure for your project, we recommend to read the guide in the Firebase documentation here.
The private features of the FirebaseDatabase item only work in combination with the FirebaseAuth item and an authorized user. The public values can be accessed also without authentication, depending on the database rules.
In order to restrict access of parts of your database to only registered users, adapt your Firebase database rules accordingly.
Refer to the following JSON for a possible set of rules. The users
branch is limited to authorized users. Only users with a FirebaseAuth::userId that matches the
one from the key may access the sub-keys and thus read the containing data. In contrast, the public
branch is readable and writeable by everyone, also unauthenticated users.
// These rules grant access to a node matching the authenticated // user's ID from the Firebase auth token // Additionally, they grant access to everyone for the "public" branch { "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } }, "public": { "$uid": { ".read": true, ".write": true } } } }
To learn more on Database Rules, we recommend to read up on the topic in the Firebase Docs.
No. If you use the database rules and a database structure as provided in the examples, you can use the FirebaseDatabase::setUserValue and FirebaseDatabase::getUserValue convenience functions to store and retrieve user-specific values. This might not be enough for some applications. For example, think of an application where you have a chat that two users can see, but everyone else can't.
If you prefer to create a complex database structure completely on your own, you can do so. Use the FirebaseAuth::userId property to restrict any sub-key to one or several specific users. This is useful if you intend to implement features such as a chat or user groups. Again, to learn how to create complex database structures and rulesets, refer to the Firebase Documentation for rules and data structure.
config : FirebaseConfig |
This property defines the account configuration to use for this item. It includes the Firebase project ID
, app ID
, API key
, database URL
and more.
To use the default Firebase account defined in google-services.json and GoogleService-info.plist, do not assign this property or assign null.
persistenceEnabled : bool |
Defines whether the database should use on-disk cache. If this property is set to false
, fetched data is only cached in memory and lost when the app is closed.
The default value for this property is true
. This is a global property in the Firebase SDK and can only be set initially when creating the first instance of FirebaseDatabase. Later changes in this or another instance won't have any effect.
A list of user-specific keys for which you want to receive real-time changes from the database. When you add a value to this list, the FirebaseDatabase::realtimeUserValueChanged signal will be fired whenever the value changes in the database.
If you don't want to receive updates for this key anymore, remove it from the list.
See also FirebaseDatabase::realtimeValueKeys and FirebaseDatabase::realtimeUserValueChanged.
A list of keys for which you want to receive real-time changes from the database. When you add a value to this list, the FirebaseDatabase::realtimeValueChanged signal will be fired whenever the value changes in the database.
If you don't want to receive updates for this key anymore, remove it from the list.
See also FirebaseDatabase::realtimeUserValueKeys and FirebaseDatabase::realtimeValueChanged.
firebaseReady() |
This signal gets emitted when the plugin is ready to use.
Use this signal instead of PluginItem::pluginLoaded(), as the QML item referenced by config might not yet be loaded when PluginItem::pluginLoaded() is called.
Note: The corresponding handler is onFirebaseReady
.
This signal gets emitted after the getValue() request has finished.
The success parameter is true, if the value was successfully read from the database. If the value can't be read, it is false.
The key parameter contains the key of the value that was requested, and value contains the value.
Note: If a value can't be read from the database, check the log output for an error description.
Note: The corresponding handler is onReadCompleted
.
This signal gets emitted whenever a key is added to the FirebaseDatabase::realtimeUserValueKeys list or an observed value gets changed.
The key parameter contains the key of the value that was observed, and value contains the value.
}
Note: The corresponding handler is onRealtimeUserValueChanged
.
See also FirebaseDatabase::realtimeUserValueKeys.
This signal gets emitted whenever a key is added to the FirebaseDatabase::realtimeValueKeys list or an observed value gets changed.
The key parameter contains the key of the value that was observed, and value contains the value.
Note: The corresponding handler is onRealtimeValueChanged
.
See also FirebaseDatabase::realtimeValueKeys.
This signal gets emitted after the setValue() request has finished.
The success parameter is true, if the value was successfully written to the database. Otherwise, it's false. In this case, the message parameter contains an error description.
Note: The corresponding handler is onWriteCompleted
.
void addRealtimeUserValueKey(string key) |
Adds a key to the FirebaseDatabase::realtimeUserValueKeys property. When you add a value to this list, the FirebaseDatabase::realtimeUserValueChanged signal will be fired whenever the value changes in the database.
See also FirebaseDatabase::realtimeUserValueKeys.
void addRealtimeValueKey(string key) |
Adds a key to the FirebaseDatabase::realtimeValueKeys property. When you add a value to this list, the FirebaseDatabase::realtimeValueChanged signal will be fired whenever the value changes in the database.
See also FirebaseDatabase::realtimeValueKeys.
Retrieves the corresponding value for the given key from the Firebase database for the specific user. Use the FirebaseDatabase::readCompleted handler to check the result.
The optional parameter callback
can be used to handle the result directly in-place. To use it, pass a JavaScript function to handle the result. The plugin will then call that function at the same time as
FirebaseDatabase::readCompleted, with the same arguments: a boolean indicating read success, the key, and the value.
Unlike FirebaseDatabase::getValue(), this function prepends users/<userId>
to the key, so it is accessed from the user-restricted branch. This
function will only work if you use a database structure similar to the one presented in the example.
The key can also be a path to a nested value, using slashes as separator. Example: Calling getUserValue("bigobject/subobject/name")
returns the property name
of an object at the path
"users/<userId>/bigobject/subobject"
.
Supported data types for returned objects are string, number and boolean. Nested objects and arrays are also supported.
Firebase database also supports limiting and filtering the returned data. This is supported by the optional parameter queryProperties
.
The optional parameter queryProperties
defines which keys and values of the database object to return. If you use this parameter, it should be a JavaScript object with one ore more of the following
properties:
orderByPriority
: If present, the queried object will have its properties ordered by their priority. The value of this property is ignored, it is recommended to use true
. Ordering by priority
makes the filter properties startAt
, endAt
and equalTo
filter by priority. Sorting by priority is the default if no other sorting order is specified.orderByKeys
: If present, the queried object will have its properties ordered by their keys. The value of this property is ignored, it is recommended to use true
. Ordering by values makes the
filter properties startAt
, endAt
and equalTo
filter by keys.orderByValues
: If present, the queried object will have its properties ordered by their values. The value of this property is ignored, it is recommended to use true
. Ordering by keys makes the
filter properties startAt
, endAt
and equalTo
filter by value.orderByChild
: If present, the queried object will have its properties ordered by values at sub-paths defined by the value of this property. Ordering by child properties makes the filter properties
startAt
, endAt
and equalTo
filter by the child property values.limitToFirst
: If present, the queried object will be limited to the first n
properties, where n
is the value of this property.limitToLast
: If present, the queried object will be limited to the last n
properties, where n
is the value of this property.startAt
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) greater than or equal to the value of this property.endAt
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) less than or equal to the value of this property.equalTo
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) equal to the value of this property.It is also possible to use startAt
, endAt
and equalTo
to filter by keys and values at the same time. To do so, provide an object as value for these properties. Example:
db.getUserValue("myvalue", { startAt: { key: "startKey", value: "startValue" } }, function(success, key, value) { if(success) { console.log("Read user value for key", key, "from DB:", value) } })
Check the official firebase query documentation for more information about how querying works in detail.
Example call using multiple query properties:
firebaseDb.getUserValue("bigqueryobject", { orderByValue: true, //order by value before limiting and filtering startAt: 5, //return only values greater than or equal to 5 endAt: 1000, //return only values less than or equal to 1000 limitToFirst: 10 //return only first 10 sub-keys/values }, function(success, key, value) { ... })
This call will return an object or array at the database path "users/<userId>/bigqueryobject"
, with only values between 5 and 1000 and limited to the first 10 entries.
Note: When querying key/value objects, the returned object keys are not actually sorted. The ordering is still relevant because it is applied before limiting, and filtering is based on the defined ordering. If you need ordered data, store and retrieve arrays instead.
Note: This function requires Firebase authentication! It will fail if the user is not logged in.
See also FirebaseDatabase::readCompleted.
Retrieves the corresponding value for the given key from the Firebase database without authentication. Use the FirebaseDatabase::readCompleted handler to check the result.
The optional parameter callback
can be used to handle the result directly in-place. To use it, pass a JavaScript function to handle the result. The plugin will then call that function at the same time as
FirebaseDatabase::readCompleted, with the same arguments: a boolean indicating read success, the key, and the value.
The key can also be a path to a nested value, using slashes as separator. Example: Calling getValue("public/bigobject/subobject/name")
returns the property name
of an object at the path
"public/bigobject/subobject"
.
Supported data types for returned objects are string, number and boolean. Nested objects and arrays are also supported.
Firebase database also supports limiting and filtering the returned data. This is supported by the optional parameter queryProperties
.
The optional parameter queryProperties
defines which keys and values of the database object to return. If you use this parameter, it should be a JavaScript object with one ore more of the following
properties:
orderByPriority
: If present, the queried object will have its properties ordered by their priority. The value of this property is ignored, it is recommended to use true
. Ordering by priority
makes the filter properties startAt
, endAt
and equalTo
filter by priority. Sorting by priority is the default if no other sorting order is specified.orderByKeys
: If present, the queried object will have its properties ordered by their keys. The value of this property is ignored, it is recommended to use true
. Ordering by values makes the
filter properties startAt
, endAt
and equalTo
filter by keys.orderByValues
: If present, the queried object will have its properties ordered by their values. The value of this property is ignored, it is recommended to use true
. Ordering by keys makes the
filter properties startAt
, endAt
and equalTo
filter by value.orderByChild
: If present, the queried object will have its properties ordered by values at sub-paths defined by the value of this property. Ordering by child properties makes the filter properties
startAt
, endAt
and equalTo
filter by the child property values.limitToFirst
: If present, the queried object will be limited to the first n
properties, where n
is the value of this property.limitToLast
: If present, the queried object will be limited to the last n
properties, where n
is the value of this property.startAt
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) greater than or equal to the value of this property.endAt
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) less than or equal to the value of this property.equalTo
: If present, the queried object will contain only properties with priority/keys/values (defined by the orderBy...
properties) equal to the value of this property.It is also possible to use startAt
, endAt
and equalTo
to filter by keys and values at the same time. To do so, provide an object as value for these properties. Example:
db.getValue("public/myvalue", { startAt: { key: "startKey", value: "startValue" }, function(success, key, value) { if(success) { console.log("Read value for key", key, "from DB:", value) } })
Check the official firebase query documentation for more information about how querying works in detail.
Example call using multiple query properties:
firebaseDb.getValue("public/bigqueryobject", { orderByValue: true, //order by value before limiting and filtering startAt: 5, //return only values greater than or equal to 5 endAt: 1000, //return only values less than or equal to 1000 limitToFirst: 10 //return only first 10 sub-keys/values }, function(success, key, value) { ... })
This call will return an object or array at the database path "public/bigqueryobject"
, with only values between 5 and 1000 and limited to the first 10 entries.
Note: When querying key/value objects, the returned object keys are not actually sorted. The ordering is still relevant because it is applied before limiting, and filtering is based on the defined ordering. If you need ordered data, store and retrieve arrays instead.
See also FirebaseDatabase::readCompleted.
void removeRealtimeUserValueKey(string key) |
Removes a key from the FirebaseDatabase::realtimeUserValueKeys property. When a key is removed from the list, its value is no longer observed and you won't be notified if the value changes in the database.
See also FirebaseDatabase::realtimeUserValueKeys.
void removeRealtimeValueKey(string key) |
Removes a key from the FirebaseDatabase::realtimeValueKeys property. When a key is removed from the list, its value is no longer observed and you won't be notified if the value changes in the database.
See also FirebaseDatabase::realtimeValueKeys.
Stores a key-value pair in the Firebase database for the current user. Use the FirebaseDatabase::writeCompleted handler to check the result.
The optional parameter callback
can be used to handle the result directly in-place. To use it, pass a JavaScript function to handle the result. The plugin will then call that function at the same time as
FirebaseDatabase::writeCompleted, with the same arguments: a boolean indicating write success, and a string with an optional error message.
Unlike FirebaseDatabase::setValue(), this function prepends users/<userId>
to the key, so it is accessed from the user-restricted branch. This
function will only work, if you use a database structure similar to the one presented in the example.
Example:
db.setUserValue("myObject", { keyA: 17, keyB: "this is my DB object" }, function(success, message) { if(success) { console.log("successfully written user object to DB") } else { console.log("DB write error:", message) } })
Note: This function requires Firebase authentication! It will fail if the user is not logged in.
See also FirebaseDatabase::writeCompleted.
Stores a key-value pair in the Firebase database without authentication. Use the FirebaseDatabase::writeCompleted handler to check the result.
The optional parameter callback
can be used to handle the result directly in-place. To use it, pass a JavaScript function to handle the result. The plugin will then call that function at the same time as
FirebaseDatabase::writeCompleted, with the same arguments: a boolean indicating write success, and a string with an optional error message.
Example:
db.setValue("public/myObject", { keyA: 17, keyB: "this is my DB object" }, function(success, message) { if(success) { console.log("successfully written object to DB") } else { console.log("DB write error:", message) } })
See also FirebaseDatabase::writeCompleted.