Firebase Realtime Database | New Era in Cloud Database

Firebase Realtime Database

Introduction

The Firebase Realtime Database gives you a chance to fabricate rich, community-oriented applications by enabling secure access to the database specifically from client-side code. Data will continue to be cached locally, and even while disconnected to the internet, real-time events keep on firing, giving the end client a responsive ordeal. At the point when the device recaptures connection, the Realtime Database synchronizes the local data changes with the remote updates that happened while the client was disconnected, consolidating any data contentions consequently.

The Realtime Database gives an adaptable, expression-based rules language, called Firebase Realtime Database Security Rules, to characterize how your data ought to remain organized and when data can be fetched from or written over. At the point when incorporated with Firebase Authentication, engineers can characterize on who approaches what information, and how they can get to it.

The Realtime Database is a very powerful NoSQL database and, in that capacity, it has several advancements and usefulness when compared with a relational database. The Realtime Database API is intended just to permit operations that can continue to be executed rapidly. Firebase allows the developer to assemble an impressive real-time experience that can serve millions of clients without bargaining on responsiveness. Along these lines, it is critical to consider how clients need to get to your information and after that structure it accordingly.

The Firebase Realtime Database supports Android, iOS, web, and more. All data is put away in JSON format and any change in data is reflected promptly by performing a sync operation across every platform. Realtime Database enables us to construct more adaptable real-time applications effortlessly. It helps users to collaborate with one another. At the point when clients are disconnected from the internet, the Realtime Database SDKs employ local cache on the device to store changes. Later when the device comes online, the local data is automatically synchronized to Realtime Database. The Realtime Database incorporates with Firebase Authentication to give basic and instinctive authentication for developers. You can utilize the Firebase security model to permit access-based client identity or with pattern coordinating on your data.

In October, 2017, Google announced Cloud Firestore, the latest real-time, scalable NoSQL database from Firebase and Google Cloud Platform. Since Firestore is still in the beta program, we will learn about Firestore, and the last chapter is dedicated to it.

Setting up a development environment

To get started, we need to integrate the Firebase SDK to the project, and it is a one-time integration. Later, we can choose any of the Firebase tools that we want to work with and add the appropriate gradle dependency.

Prerequisites

To develop Firebase applications, you can surely use your development environment; the essential requirements are as follows:

  1. Your favorite operating system (Windows, macOS, or Linux)
  2. Determine whether you have the latest JRE installed on your operating system
  3. Install the latest version of JDK or Open JDK
  4. Install the newest version of Android Studio (at the time of writing, the most recent stable version is 2.3.3 and 3.0 is still in beta, or any newer version should also be excellent)
  5.  Android SDK with one complete API will be very significant

Configuring Firebase in Android projects

There are two ways that you can connect Firebase to your Android project, from the Firebase console creating the new project and adding the dependencies and Google config file. The other way is just to add Firebase support to an Android project directly from Android Studio:

  1. The usual way of connecting Firebase is to visit the Firebase console at https://console.firebase.google.com/
  2. Create a new project using the Add Project button, and if you already have an existing project, you are free to choose it
  3. In the overview section of the console, you can choose to add an Android application by clicking on the relevant button and add the necessary information to the fields
  4. Download the google-services.json file, add it to your project’s app folder root, and the classpath gradle dependencies in the project’s gradle file
  5. To reduce the effort, we can make Android Studio do all this for us by choosing the Tools Firebase menu option and clicking on the Firebase tools that you want to integrate from the list
  6. After you chose the Firebase tool, tap on Save and retrieve data
  7. In the next window panel, you will see options such as Launch in the browserConnect your app to Firebase, and so on, click on theConnect your app to Firebasebutton and select your project or you can create the new project in the Connect to Firebase window
  8. Go back to the Firebase panel and click on theAdd the Realtime Database to your applicationbutton

Since we have connected to Firebase, it is as simple as it sounds, all we have to do is select the Add the Realtime Database to your application button in the Firebase assistance window, you will see a dialog for requesting your authorization to change the gradle file with a few dependencies. Tap on Accept Changes, now we are all set to explore Realtime Database abilities.

Reading and writing to Realtime Database

Since the nuts and bolts of the Firebase Realtime Database are set up, the next stage is to explore how data can be composed or written to a database tree from an Android application. This section will give points of interest on the most proficient method to write, how to erase database tree nodes, and furthermore, outline a few strategies for taking care of database write errors.

Database reference

Essentially, a reference to the database is required. Every Firebase project has its own particular devoted Realtime Database items of which can be examined by opening the project inside the Firebase console and picking the Database option. Inside the console, panels can be selected to show data trees set away in the database, the rules outlined for fetching the access, database use estimations, and so on.

Firebase databases are usually Representational State Transfer (REST) endpoint references, which we will use to add the data. We will understand how to fetch the reference with the following code snippet:

[code lang=”java”]
// fetch reference database
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference("Donor/Name");
[/code]

Reading and writing to Realtime Database
Since the nuts and bolts of the Firebase Realtime Database are set up, the next stage is to explore how data can be composed or written to a database tree from an Android application. This section will give points of interest on the most proficient method to write, how to erase database tree nodes, and furthermore, outline a few strategies for taking care of database write errors.

Database reference
Essentially, a reference to the database is required. Every Firebase project has its own particular devoted Realtime Database items of which can be examined by opening the project inside the Firebase console and picking the Database option. Inside the console, panels can be selected to show data trees set away in the database, the rules outlined for fetching the access, database use estimations, and so on.

Firebase databases are usually Representational State Transfer (REST) endpoint references, which we will use to add the data. We will understand how to fetch the reference with the following code snippet:

Copy
// fetch reference database
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference(“Donor/Name”);
The preceding code will fetch the reference, on the off chance that the particular path does not exist now, it is composed automatically inside the tree when data is written at that location.

Writing into Realtime Database

Fetch an instance of your database employing getInstance() and reference the location you need to write. You can write most of the primitive data types as they also include Java objects:

[code lang=”java”]
// Write a message to the database
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference("Donor/Name");
mDbRef.setValue("Parinitha Krishna");
[/code]

The following screenshot explains the dashboard changes after running the preceding code:
firebase

If you notice that there aren’t any changes in the dashboard from the write operation, we shall attach an onFailure callback like the following for identifying what’s stopping it:

[code lang=”java”]
// Write a message to the database
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference("Donor/Name");
mDbRef.setValue("Parinitha Krishna").addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
});
[/code]

Reading from Realtime Database

After writing the data into Firebase now it’s time to read what we have written. Firebase Realtime Database syncs all the data in real time across platforms and devices. So we have an onDatachanged() callback to read the data:

[code lang=”java”]
// Read from the database
mDbRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String value = dataSnapshot.getValue(String.class);
Log.d(TAG, "Value is: " + value);
}

@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
[/code]

Structuring the data with objects
Create a model class with constructors and declare a string to fetch the database reference for a unique key to add the list of objects. The model class is as follows:

[code lang=”java”]
public class Users {

private String Name;
private String Email;
private String Phone;

public Users() {
}

public String getName() {
return Name;
}

public void setName(String name) {
Name = name;
}

public String getEmail() {
return Email;
}

public void setEmail(String email) {
Email = email;
}

public String getPhone() {
return Phone;
}

public void setPhone(String phone) {
Phone = phone;
}

public Users(String name, String email, String phone) {
Name = name;
Email = email;
Phone = phone;
}

}
[/code]

Now in the activity class using the DatabaseReference class we can set the object value to Firebase, as follows:

[code lang=”java”]
public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
private FirebaseDatabase mDatabase;
private DatabaseReference mDbRef;
private String userId;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Write a message to the database
mDatabase = FirebaseDatabase.getInstance();
mDbRef = mDatabase.getReference("Donor/Name");

//Setting firebase unique key for Hashmap list
String userId = mDbRef.push().getKey();
// creating user object
Users user = new Users("Hillary", "hillary@xyz.com", "90097863873", "Tokyo");

mDbRef.child(userId).setValue(user);

}
}
[/code]

Reading the objects from Firebase

To read the object data from Firebase Realtime ValueEventListner() whenever there is an update in the database in onDatachanged callback we can read the data changes:

[code lang=”java”]
mDbRef.child(userId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {

Users user = dataSnapshot.getValue(Users.class);

Log.d(TAG, "User name: " + user.getName() + ", email " + user.getEmail());
}

@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
[/code]

When the code is executed, it will result in fetching the data tree to your project. It is up to us how we make use of the data.

Since we are using unique key mechanism the data will be added under the Name reference with a unique identifier:

Reading value changes

In Firebase Realtime Database to listen to the data changes, we have addValueEventListener for listening to the multiple nodes. In case you want to check the single value by adding addListenerForSingleValueEvent(), we can do that as well:

[code lang=”java”]
mDbRef = mDatabase.getReference("/Donor/name");

ValueEventListener changeListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {

}

@Override
public void onCancelled(DatabaseError databaseError) {

}
};

mDbRef.addValueEventListener(changeListener);
[/code]

When a listener is not required, it should be detached from the database reference object as follows:

[code lang=”java”]
mDbRef.removeEventListener(changeListener);
[/code]

Parsing the DataSnapshot object

In a simple way, DataSnapshot can be accessed through the getValue method. We can use the child() method to reach to a specific path of a snapshot. Consider the following example code snippet that fetches the title:

[code lang=”java”]
String title = mDataSnapshot.child("message1").child("title").getValue(String.class);
[/code]

And all the children can be accessed using the getChildren() method. Consider the following code that is reading all the child details inside a for each loop:

[code lang=”java”]
for (DataSnapshot child : mDataSnapshot.getChildren()) {
Log.i(TAG, child.getKey());
Log.i(TAG, child.getValue(String.class));
}
[/code]

Updating data

To update data, we can use the setValue() method by passing updated values. You can likewise utilize updateChildren() by passing the way to update data without exasperating other child nodes:

[code lang=”java”]
String newEmail = "ashokslsk@gmail.com";
mDbRef.child(userId).child("email").setValue(newEmail);
[/code]

The following screenshot illustrates the updated value for the email field:

Writing HashMaps to Realtime Database

By using the updateChildren() method of the database reference class, we can write the HashMap data structure into Firebase Realtime Database. Let’s create a HashMap and add different key-value pairs, each should be reflected in the Realtime Database:

[code lang=”java”]
// Write a message to the database
mDatabase = FirebaseDatabase.getInstance();
mDbRef = mDatabase.getReference("Donor/Name");

//Writing Hashmap
Map<String, Object> mHashmap = new HashMap<>();

mHashmap.put("Name 1/title", "Ashok");
mHashmap.put("Name 1/content", "Parinitha");
mHashmap.put("Name 2/title", "Krishna");
mHashmap.put("Name 2/content", "Sumuthra");

mDbRef.updateChildren(mHashmap);
[/code]

The following screenshot illustrates the HashMap writing in the Firebase console:

Realtime Database and lists

Lists are compelling data structures and they help in numerous use cases. Firebase has excellent support for HashMap and lists. Users can append the data according to the unique key from Firebase, or you can create your logic to create a unique identifier. Using the push() method a user can insert the data, and there are many ways to filter and match the data pushed. Let’s see how the push() method helps in creating a list. As usual first grab the reference to the database and then using the push() method get the unique key. Using the push() method we can add a new child:

[code lang=”java”]
// Write a message to the database
mDatabase = FirebaseDatabase.getInstance();
mDbRef = mDatabase.getReference("Donor/Name");

//Setting firebase unique key for Hashmap list
String key = mDbRef.push().getKey();

mDbRef.child(key).setValue("First item");
[/code]

Apart from allowing a database to create a list, it is also necessary to receive a data-changed notification from the list. This can be achieved through adding child event listeners. These listeners will notify the app when there is a new child added. We need to implement a couple of callbacks when we use this listener. Most commonly there is the onChildAdded() method when a child is added, and it sends a new data snapshot with data added. Note that onChildChanged() is called when there is an update to the existing node, and onChildRemoved() is called when a child node is removed. However onChildMoved() is called when any alterations change the list order:

[code lang=”java”]
ChildEventListener childListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};

mDbRef.addChildEventListener(childListener);
[/code]

There are many ways to perform the query on the list. Firebase has a class named Query to access the database inside the application on specified criteria:

[code lang=”java”]
Query mQuery = mDbRef.orderByKey();

ValueEventListener mQueryValueListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> snapshotIterator = dataSnapshot.getChildren();
Iterator<DataSnapshot> iterator = snapshotIterator.iterator();
while (iterator.hasNext()) {
DataSnapshot next = (DataSnapshot) iterator.next();
Log.i(TAG, "Value = " + next.child("name").getValue());
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};

mQuery.addListenerForSingleValueEvent(mQueryValueListener);
[/code]

Deleting data

To delete data, you can call the removeValue() method onto database reference. You can likewise pass null to the setValue() method, which does the same delete operation:

[code lang=”java”]
//Removes the entire child
mDbRef.child(userId).removeValue();
//Passing null to remove the calue
mDbRef.chile(userId).child("name").setValue(null);

// Similarly Hashmap can also be removed
Map<String, Object> mHashmap = new HashMap<>();

mHashmap.put("Name 1/title", null);
mHashmap.put("Name 1/content", null);
mHashmap.put("Name 2/title", null);
mHashmap.put("Name 2/content", null);
[/code]

The following screenshot shows the Firebase console reaction for the delete operation:

Offline capabilities

At the point when clients are disconnected from the internet, the Realtime Database SDKs employ local cache on the device to store changes. Later when the device comes online, the local data is automatically synchronized to Realtime Database. We can enable disk persistence to save the data offline from the following lines of code:

[code lang=”java”]
//Offline support
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
[/code]

We will be happy to hear your thoughts

Leave a reply

Register New Account
Reset Password