To start using the Realtime Database package within your project, import it at the top of your project files:
Before using Firestore, you must first have ensured you have initialized FlutterFire.
By default, this allows you to interact with the Realtime Database using the default Firebase App used whilst installing FlutterFire on your
platform. If however you'd like to use it with a secondary Firebase App, use the
Realtime Database stores data as JSON, however enables you to access nodes of the data via a
For example, if your data is stored as the following:
You can create a reference to a node by providing a path:
users: Creates a reference to the entire "users" object
users/123: Creates a reference to the "123" user object
users/123/name: Creates a reference to a property (with the value of "John")
To create a new
DatabaseReference, pass the path to the
If you do not provide a path, the reference will point to the root of your database.
DatabaseReference provides some useful utilities to access sub-nodes, access the parent
(if one exists) and modify data.
The Realtime Database allows you to read data either once, or be notified on any changes to the node and it's children.
To read the data once, call the
once method on a
The result of a read is a
DatabaseEvent. This contains a
DataSnapshot of the data at the location of the reference,
along with some additional metadata such as the reference key or whether the node exists in your database.
If you'd instead like to subscribe to realtime updates, the
onValue method returns a
Anytime data within the
users/123 node changes, the Stream will fire a new event.
Without specifying any query constraints, reading data will return all data within the node. If you wish to query your node for a subset of data, the package provides utilities to do so. For example, we could choose to order our data by an "age" property, and limit the returns returned:
Alternatively we could instead return users between certain ages by using
When modifying data we can either
set the data (overwrite everything which exists at a node) or
update specific parts of a node.
To set data, call the
set method on a
To update data, provide a
Map where the keys point to specific nodes of the parent
update method accepts a sub-path to nodes, allowing you to update multiple nodes on the database at
To remove data from your database, call the
remove method (or
set with a
Removing a node will delete all data, including nested objects.
When working with data that could be corrupted by concurrent modifications, such as incremental
counters, you can use a transaction. A
TransactionHandler takes the current state of the data as
an argument and returns the new desired state you would like to write. If another client writes to
the location before your new value is successfully written, your update function is called again with the new
current value, and the write is retried.
By default, events are raised each time the transaction update function runs. So if it is run
multiple times, you may see intermediate states. You can set
applyLocally to false to suppress these
intermediate states and instead wait until the transaction has completed before events are raised:
The result of a transaction is a
TransactionResult, which contains information such as whether
the transaction was committed, and the new snapshot:
If you wish to safely abort a transaction from executing, you can throw a
Alternatively we're able to execute atomic operations on the server to ensure there is no chance of conflicts or out-of-sync updates.
For example, we can increment an age and set a timestamp on the server, rather than the client by using the
Firebase Database clients provide simple primitives that you can use to write to the database when a client disconnects from the Firebase Database servers. These updates occur whether the client disconnects cleanly or not, so you can rely on them to clean up data even if a connection is dropped or a client crashes. All write operations, including setting, updating, and removing, can be performed upon a disconnection.
First, create a new
OnDisconnect instance on a
Next apply any operations which should trigger when the user disconnects. For example, we can easily create a presence system by storing a boolean value on a user if they are online, and remove it if they go offline:
OnDisconnect instance supports
You can remove any committed operations at anytime by calling the
If you are using the local Firestore emulators,
then it is possible to connect to this using the
useDatabaseEmulator method. Ensure you pass the correct port on which the Firebase emulator is running on.
Ensure you have enabled network connections to the emulators in your apps following the emulator usage instructions in the general FlutterFire installation notes for each operating system.