Firebase Android Tutorial Part 3 : Firebase Realtime Database

What is Realtime database :

  • It is a cloud hosted database , stores data as JSON and every connected app is synchronised to it always. If we have an cross-platform app, all apps will use one single Realtime Database instance.

  • This database is available offline also. So, application will always has access to it. If the app comes back to online, data is automatically synced again.

  • We can  define our security rules to the database.

  • Also we can enable Disk Persistence so that user can access data even if the app loses connection. Once the internet connection is re-established, it will sync the data with Firebase Realtime Database.

In this tutorial, we will use the previous application as it is already configured with Firebase.

If you are not following our tutorials, you can check this tutorial to configure your project .

Gradle dependency :

Add the following dependency to your build.gradle file :

compile 'com.google.firebase:firebase-database:9.2.0'

**Project Setup : **

  1. We are using the same project from the previous tutorial. Add one Text View,below ”SignUp”, clicking on which will start one new Activity .
<TextView
    android:text="Test RealTime Database"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/signUp"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="35dp"
    android:id="@+id/realTimeDatabase" />
  1. Create one new Activity as RealTimeActivity with layout activity_real_time.xml

  2. Clicking on ”Test RealTime Database” text will start this new activity.

So, add the below code snippet inside  your onCreate() method of MainActivity’s  as :

realTimeDataText = (TextView)findViewById(R.id.realTimeDatabase);
realTimeDataText.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent i = new Intent(MainActivity.this, RealTimeActivity.class);
        startActivity(i);
    }
});
  1. Change your activity_real_time as below :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_real_time"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_centerHorizontal="true"
    tools:context="com.codevscolor.firebasedemo.realtimedatabase.RealTimeActivity">

    <Button
        android:text="Add data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:id="@+id/button_add"
        android:onClick="addData"
        android:layout_gravity="center_horizontal"/>

    <Button
        android:text="Add More data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_add_more"
        android:onClick="addMore"
         />

    <Button
        android:text="Append data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_append_data"
        android:onClick="appendData"
         />

    <Button
        android:text="Delete data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_delete"
        android:onClick="deleteData"
         />

    <Button
        android:text="Find data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_find"
        android:onClick="findData"
        />

    <Button
        android:text="Update data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_update"
        android:onClick="updateData"
        android:layout_marginBottom="23dp" />

</LinearLayout>

We have added 6 buttons that will be used to_** add / append/delete/find**_ and update data.

  1. Change Permission to read/write data :

1. Go to "database" -> "rules" tab and change as below :
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Click publish . You can check here about other rules.

2. Start your app and click on "Add data" button.It will call "_**addData**_" method :
public void addData(View view){
       DatabaseReference myRef = database.getReference("message");

       myRef.setValue("Hello, World!");
       myRef.addValueEventListener(new ValueEventListener() {
           @Override
           public void onDataChange(DataSnapshot dataSnapshot) {

           }

           @Override
           public void onCancelled(DatabaseError databaseError) {
               Toast.makeText(RealTimeActivity.this, "Oops " + databaseError.getMessage(), Toast.LENGTH_LONG).show();
           }
       });
   }

“database” is Firebase Database instance :

private FirebaseDatabase database;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_real_time);
    database = FirebaseDatabase.getInstance();
}

If you are not getting any error toast msg, that means data is saved to Firebase. If everything works fine, you will see some values inside your “Database” tab:

2016 06 30 1742

Here we are using setValue() to save “String” variable to Firebase. We can also save Long, Double, Boolean, Map<String,Object>, List or custom Java Object.

3. Saving a custom java object :


  1. Create a new "Person.java" class as below :
import com.google.firebase.database.IgnoreExtraProperties;

@IgnoreExtraProperties
public class Person {
    public String name;
    public int age;

    public Person(){

    }

    public Person(String pName, int pAge) {
        this.name = pName;
        this.age = pAge;
    }

}

Remember to make all variables “public”, otherwise it will not work.

  2. Now add one method "addMore" that will be called if "Add More" button is clicked :
public void addMore(View v) {
    DatabaseReference myRef = database.getReference("series");
    Person phoebe = new Person("Phoebe", 26);
    Person rachel = new Person("Rachel", 26);
    Person ross = new Person("Ross", 31);
    Person monica = new Person("Monica", 26);
    Person joey = new Person("Joey", 29);

    myRef.child("friends").child("1").setValue(phoebe);
    myRef.child("friends").child("2").setValue(rachel);
    myRef.child("friends").child("3").setValue(ross);
    myRef.child("friends").child("4").setValue(monica);
    myRef.child("friends").child("5").setValue(joey);

    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(RealTimeActivity.this, "Oops " + databaseError.getMessage(), Toast.LENGTH_LONG).show();
        }
    });
}

We need one key to store nodes to the database. Here we are using “1”,“2”,“3”,“4”,“5” as key for different objects . Finally we are calling setValue method to save on our database.

  3. Append Childs : 

Clicking on “Append Data” button will add one more object to the database.

public void appendData(View v){
 DatabaseReference myRef = database.getReference("series");
 Person chandler = new Person("Chandler",29);
 String key = myRef.child("friends").push().getKey();
 myRef.child("friends").child(key).setValue(chandler);

 myRef.addValueEventListener(new ValueEventListener() {
 @Override
 public void onDataChange(DataSnapshot dataSnapshot) {

 }

 @Override
 public void onCancelled(DatabaseError databaseError) {
 Toast.makeText(RealTimeActivity.this,"Oops "+databaseError.getMessage(),Toast.LENGTH_LONG).show();
 }
 });
}

Here we are creating one new key using push().getKey() method. This method returns one new key each time.Check your database, it will add one new node with a new random key.

  4. Delete Data:

We can delete data by calling removeValue() on a Database reference . Or we can delete it by specifying null using setValue() or updateChildern(). Clicking on “Delete Data” will remove “Hello World ” node we have added previously  

public void deleteData(View v) {
    DatabaseReference myRef = database.getReference("message");
    myRef.setValue(null);
}
  5.  Sort and Find Data :We can create one Query object and sort it by any of its properties. Following method will be called if "Find Data" button is clicked.
public void findData(View v) {
    //sorting and searching
    final DatabaseReference myRef = database.getReference("series/friends");
    Query query = myRef.orderByChild("name").equalTo("Chandler");
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
                String name = (String) messageSnapshot.child("name").getValue();
                Long age = (Long) messageSnapshot.child("age").getValue();
                Toast.makeText(RealTimeActivity.this, "found " + name +" age: "+age, Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

addListenerForSingleValueEvent is called only once . onDataChange method will be called if any node with ”name” ”Chandler” is found.

If found one Toast msg is displayed with name and age of that Person.

  6. Update Data:

We can update any data if we have Database Reference and key for that node. following method will update age of “Phoebe” as 27.

public void updateData(View v){
    final DatabaseReference myRef = database.getReference("series/friends");
    myRef.child("1").child("age").setValue(27);
}

That’s it. You can check full Documentation on Android for “Realtime Database” here

 

If you have any queries, kindly let me know.