Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Firebase for Android Development

You're reading from   Mastering Firebase for Android Development Build real-time, scalable, and cloud-enabled Android apps with Firebase

Arrow left icon
Product type Paperback
Published in Jun 2018
Publisher Packt
ISBN-13 9781788624718
Length 394 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Ashok Kumar S Ashok Kumar S
Author Profile Icon Ashok Kumar S
Ashok Kumar S
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface 1. Keep It Real – Firebase Realtime Database FREE CHAPTER 2. Safe and Sound – Firebase Authentication 3. Safe and Sound – Firebase Crashlytics 4. Genie in the Cloud – Firebase Cloud Functions 5. Arsenal for Your Files – Firebase Cloud Storage 6. Not Just a Keeper, Firebase Hosting 7. Inspection and Evaluation – Firebase Test Lab 8. A Smart Watchdog – Firebase Performance Monitoring 9. Application Usage Measuring and Notification, Firebase Analytics, and Cloud Messaging 10. Changing Your App – Firebase Remote Config and Dynamic Links 11. Bringing Everyone on the Same Page, Firebase Invites, and Firebase App Indexing 12. Making a Monetary Impact and Firebase AdMob and AdWords 13. Flexible NoSQL and Cloud Firestore 14. Analytics Data, Clairvoyant, Firebase Predictions 15. Training Your Code and ML Kit 16. Other Books You May Enjoy

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:

// 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:

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

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

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:

// 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());
}
});
Before we compile the preceding code snippet, we need to change the rules to be true since we are no longer using any authentication service. Go to the Rules tab and change the read and write service to be true. When we do this, remember that the endpoint is publicly accessible by anybody who has the URL:

{
"rules": {
".read": true,
".write": true
}
}

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:

// 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());
}
});

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: 

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;
}

}

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

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);

}
}

The preceding code will add the object into Firebase as follows: 

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:

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());
}
});

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:

mDbRef = mDatabase.getReference("/Donor/name");


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

}

@Override
public void onCancelled(DatabaseError databaseError) {

}
};

mDbRef.addValueEventListener(changeListener);

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

mDbRef.removeEventListener(changeListener);

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:

String title = mDataSnapshot.child("message1").child("title").getValue(String.class);

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:

for (DataSnapshot child : mDataSnapshot.getChildren()) {
Log.i(TAG, child.getKey());
Log.i(TAG, child.getValue(String.class));
}

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:

String newEmail = "ashokslsk@gmail.com";
mDbRef.child(userId).child("email").setValue(newEmail);

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:

// 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);

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:

// 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");

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:

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);

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: 

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);

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:

//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);

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:

//Offline support
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
You have been reading a chapter from
Mastering Firebase for Android Development
Published in: Jun 2018
Publisher: Packt
ISBN-13: 9781788624718
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at R$50/month. Cancel anytime