Skip to content

Getting started with Firebase Realtime Database on Android

Cloud Firestore may be out (in its beta) and it does look to be overshadowing its little brother, but there are a number of good reasons to stick to the Realtime Database. For instance, Realtime Database is just better than Firestore at being “realtime”. If you want to find out more about that, you should check out Realtime Database vs Firestore. Enough on comparisons though, let’s jump in to implementing the Realtime Database.

But before that, I really recommend you check out this book, The Definitive Guide to Firebase by Laurence Moroney. Whether you’re getting started on Firebase or you’re pretty experienced already but still hungry for a deeper understanding, this knowledge will prove invaluable.

 

Setting up the Requirements

  1. If you haven’t already, install the Firebase SDK. I’ve done a tutorial about it which you can find here.
  2. Add the dependency to your app-level build.gradle file.
compile 'com.google.firebase:firebase-database:11.8.0'

 

Configuring Firebase Database Rules

// These rules give anyone, even people who are not users of your app,
// read and write access to your database
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

If we try to write to our database now, we’ll get permissionDenied errors. That’s because by default, the rules on your database are set to only allow authenticated users to read and write data on your database. The ins and outs of writing these rules could be a whole article of itself.

If your app is still in development, keep it to public for now so you can immediately get to reading and writing data (but don’t forget it to change it later for security). Otherwise, check out the official docs for it.

Navigate to the Rules tab on the data viewer of the Realtime Database in the Firebase Console. Replace the default rules with the above code to make it public.

 

Writing Data to the Database

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();

myRef.child("user").child("name").setValue("Montgomery");

When either reading or writing from the database, we always have to start by getting a reference to the database. Calling getReference() on an instance of the Firebase Database will give us a reference of the root of our database. We use child() on the reference to go down the hierarchy and return another reference.

Finally, we call setValue() on a reference to give that reference a value. Simple, isn’t it?

Deleting Data from the Database

If you want to delete a field instead of just overwriting, just call removeValue() on the reference. Simple enough.

 

Retrieving Data from the Database

To fetch data from the database, you need to add an event listener to a database reference. There are 3 which all have slightly varied purposes:

  1. ChildEventListener – Calls seperate functions for when children of that reference are added, updated, deleted, etc. onChildAdded is called upon attaching
  2. ValueEventListener – Calls a function when the value of that reference is changed. onDataChanged is called upon attaching
  3. SingleValueEventListener – A value event listener that only runs once
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference().child("user");
userRef.child("name").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String name = dataSnapshot.getValue(String.class);
        ((TextView)findViewById(R.id.nameTextview)).setText(name);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w("MainActivity", "Listener on userRef cancelled: " + databaseError);
    }
});

Once again, start by getting a reference to the location of where you want to fetch your data. For a one-time data retrieval, add a ListenerForSingleValueEvent. This will generate two methods, onDataChanged and onCancelled.

In the onDataChanged method, a DataSnapshot is passed. Calling getValue() will return the data contained in the reference pointed by that snapshot (the same reference you added your listener to). Just like references, you call navigate down the snapshot with child(), however, you can’t navigate up. The onCancelled method is given to you to handle the error gracefully in the case that the program fails to retrieve data for reasons such as internet connection or permission denial.

Retrieving data in Realtime

userRef.removeEventListener(valueEventListener);

To start fetching from your database in Realtime,  all you have to do is replace the SingleValueEvent listener with a ValueEventListener or a ChildEventListener. The rest stays the same! The only thing you have to be aware of is to remove the event listener when the user gets out of the activity, preferably in the onStop method of your activity.

That’s because these listeners can still be called when the user is no longer in that activity which usually leads to an IllegalStateException and crashes your app. Yikes.

 

Get the Example App Source Code

With every tutorial, I try to write an example app to help you experiment and understand the topic better. Check it out here.