How to read / write (read / write) data to the firebase realtime database on the Web - boreddev

How to get a reference to the database (database reference)

To read / write data from the database, you need to initialize an instance object from firebase.database.Reference :

// Khởi tạo 1 tham chiếu tới database
var database = firebase.database();

Reading / writing data

This article will cover the basics of retrieving data and how to organize and perform firebase data filtering.

Firebase data is retrieved by attaching a listener function to a referencefirebase.database.Reference. The listener function is triggered when data data is initialized or whenever this data data is changed.

Note: By default, read / write access to the database is restricted, allowing only authorized users to have read / write access. When you are new to firebase, you can configure these rules so that write / read access is not restricted to the database by following the link. configure your rules for public access . This configuration will make your database open to everyone, even those who are not using your app, so you need to make sure to restrict database access when you reset it. authentication mode.

The basic way to write data

For basic write operations, you can use the set () method to save data to a specific database reference. Consider the example of a social blogging application that can add a new user by doing set () as follows:

function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl

The set () method will overwrite the data at the location node users/$userId, and note that it overwrites all child nodes of this node if any.

How to listen to value events

To read the data of a node at a path location and listen for the event when its value value changes, you use the method on() or once() of referencefirebase.database.Reference to listen to the event.

valueRead (read) the data and listen for the node's value change and its entire child node at a path location

You can use the event value event to read the data value of a node at a specific path location. This event will be triggered when the data value at the node or the value of one of its child nodes changes. The event callback function takes a snapshot of the data (the status of the data at the time of the event) including the data value at the node (note that this data value includes all the values ​​of its child nodes. ). If the node does not contain data, the snapshot will return false when you call the method exists()and return null when you make the method call value()

Attention: valueA node's event is triggered every time the data value changes, including changes occurring on its child nodes. To limit the size of snapshots, you should only listen to events value The event at the node has the lowest level of depth when really needed to capture the change of the data. For example, listening value The event at the root of the database is not something to do.

Consider the following example to figure out how the social blogging application gets the star number of a post from the database:

var starCountRef = firebase.database().ref('posts/' + postId + '/starCount');
starCountRef.on('value', function(snapshot) {
updateStarCount(postElement, snapshot.val());

The listener listener function takes a snapshot as the input parameter, which contains the data of the node at a specified position, at the time the event occurred. You can retrieve data in the snapshot by calling the method val().

How to read data once only

In some cases, you might want to get a snapshot of the data without having to listen to the data event being changed, like creating a UI element that you don't want to change. . You can use method once() to simplify handling in this case: The event will only trigger once and will not trigger again.

This is useful for data that needs to be loaded only once and doesn't expect the data to change. For example, in the blogging app in the previous example, we used the method once() to load user profile information when they start writing a new post:

var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' + userId).once('value').then(function(snapshot) {
var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
// ...

How to perform update and detele data

How to update fields

Assuming you want to write data to a few specific child nodes of a node and don't want to have to overwrite other children nodes, you must use the update()

When calling method update(), you can update the child values ​​(the values ​​of the child nodes) with a higher depth by defining a path location as a key key. If data is stored in multiple locations (for better scaling), then you may need to update all of those nodes by using data fan-out.

Consider, for example, a social blogging app that creates posts and at the same time updates this post to the latest post list and the latest active feed list of the user who created the post:

function writeNewPost(uid, username, picture, title, body) {
// Dữ liệu 1 bài post.
var postData = {
author: username,
uid: uid,
body: body,
title: title,
starCount: 0,
authorPic: picture

// Tạo khóa key cho bài post mới.
var newPostKey = firebase.database().ref().child('posts').push().key;

// Ghi dữ liệu data của bài post mới đồng thời vào danh sách posts list và danh sách post list của user
var updates = {};
updates('/posts/' + newPostKey) = postData;
updates('/user-posts/' + uid + '/' + newPostKey) = postData;

return firebase.database().ref().update(updates);

This example uses methods push() to create a post in the node that contains all posts for all users at the location /posts/$postid and also get the key lock. The key lock can also be used to create a post that is on the list of user posts in place /user-posts/$userid/$postid

By using these path locations, you can perform simultaneous updates to different locations in the JSON tree with only one call. update(), similar to the example above also create new posts in both positions. This simultaneous update operation is atomic so as a result every update succeeds or fails.

Add to the completion callback

If you want to know when your data has been successfully processed, you can add a completion callback function. Both methods set() and updtae() Each parameter will receive an additional completion callback, this callback function will be called when the database write operation is successful. If the call is unsuccessful, the callback will take the error object as an argument, to determine the cause of the error:

  firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl
}, function(error) {
if (error) {
// The write failed...
} else {
// Data saved successfully!

Delete data

The simplest way to delete data is to call the method remove() at the node you want to delete.

You can also delete by assigning null into the value value for write operations like set() good update(). You can use this technique with update() to delete multiple child nodes in a single api call.

How to receive Promise

To know when the data has been successfully processed to the Firebase Realtime Database on the server, you can use 1 Promise . Both methods set() and update() all return 1 Promise, you can use it to know when to successfully write to the database.

How to turn off listeners

Callbacks can be removed using methods off(). You can delete a listener by passing it as an argument of off(). Method call off() At a node that has a specific position without passing parameters to delete all the listeners at that node has that position.

Method call off() on the parent node, it will not automatically delete the listerners registered by its child nodes; method off() You will have to make multiple calls on the child listerners to remove the callback on the child nodes.

How to save data securely using transactions

When performing data processing, it is very likely that data is corrupted, lost by simultaneous modification operations, such as automatic incremental counting, you can use manipulation physical transaction operation to remedy this situation. This action is similar to the update function and takes a parameter called completion callback. This update function takes the current state state of the data data as a parameter and returns the new state state you want to write. If another client wants to write to the same node at the same location, before the new value value is written successfully, the update function will be called again with the new value state and the write operation will be repeated.

For example, in a social blogging app, you can allow users to star or un-star to vote on posts and want to save them, see how many stars have been voted for the post as follows:

function toggleStar(postRef, uid) {
postRef.transaction(function(post) {
if (post) {
if (post.stars && post.stars(uid)) {
post.stars(uid) = null;
} else {
if (!post.stars) {
post.stars = {};
post.stars(uid) = true;
return post;

By using the transaction, it will prevent counting stars from becoming inaccurate when there are multiple users voting at the same time at the same time. If the transaction is denied, then the server will return the current value to the client, and will run the transaction again with the updated value. This process will be repeated until the transaction is accepted or you cancel the transaction.

Note: Because the update function can be called multiple times, you may need to consider processing when the data null. Even if the data exists on the remote database, it may not be cached locally when the transaction function executes, resulting in an initialized value of null.

Write data offline

If the client loses network connectivity, your app will still function properly.

Every client connected to the firebase database stores the internal versions right in the client of any active data itself. When data is written, it is first written locally. The firebase client then synchronizes this data with the remote database on the server in the most optimal way.

As a result, the whole process of writing to the database will trigger events in the local immediately, before any data is written to the server. This means that your app responds almost immediately, regardless of network latency.

When the network connection is reset, your app will receive a set of appropriate events, so the client will synchronize with the current state in the server, without having to write any more. any code at all.

Note: Firebase Realtime Database Web APIs do not store data data offline outside the session. To handle writes that can be stored on the server, the web page must not be closed before data is written to the server.