How to use Firestore Database, LiveData and ViewModel in Android

Today’s topic in my android cloud Firestore database example code might appear intimidating if you are not familiar with android LiveData and ViewModel concepts.

LiveData and ViewModel are part of Android Architecture Components. To learn more about Architecture Components in Android, I have add a link to its developers guide here.

I wrote a tutorial previously about Room, LiveData and ViewModel. You can also have a go at it.

Simple Code Example

We will create a simple application to illustrate what we have been learning.

We are going create two java classes – a class that extends ViewModel and another class that extends the LiveData class.

The LiveData class type is Task class of type DocumentSnapshot.

CREATE A NEW ANDROID PROJECT

  • Open Android Studio
  • Go to file menu
  • Select  new
  • Enter project name
  • Enter activity name
  • Select Default Activity
  • Click on finish button to create a new android project

activity layout file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp"
    android:background="#CACACA">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="title"
        android:textSize="20sp"
        android:layout_marginTop="90dp"/>

    <View
        android:id="@+id/view1"
        android:layout_width="match_parent"
        android:layout_height="2sp"
        android:layout_below="@id/title"
        android:background="@color/colorAccent"/>

    <TextView
        android:id="@+id/body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="body"
        android:textSize="30sp"
        android:layout_below="@id/view1"/>

</RelativeLayout>

activity class

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import android.os.Bundle;
import android.widget.TextView;

import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;

public class FirestoreActivity8 extends AppCompatActivity {
    private TextView title;
    private TextView body;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_firestore8);
        title = (TextView)findViewById(R.id.title);
        body = (TextView)findViewById(R.id.body);
        ViewModel8 viewModel8 = ViewModelProviders.of(this).get(ViewModel8.class);
        LiveData<Task<DocumentSnapshot>> liveData = viewModel8.getdataSnapshotLiveData();
        liveData.observe(this, new Observer<Task<DocumentSnapshot>>() {
            @Override
            public void onChanged(Task<DocumentSnapshot> task) {
                if(task.isSuccessful()){
                    DocumentSnapshot documentSnapshot = task.getResult();
                    title.setText(documentSnapshot.get("title").toString());
                    body.setText(documentSnapshot.get("body").toString());

                }
            }
        });
    }
}

ViewModel8 .java

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;

import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;

public class ViewModel8 extends ViewModel {
    private static final FirebaseFirestore mDatabase = FirebaseFirestore.getInstance();
    private final FirestoreQueryLiveData liveData = new FirestoreQueryLiveData(mDatabase.collection("AndroidView").document("Post"));

    @NonNull
    public LiveData<Task<DocumentSnapshot>> getdataSnapshotLiveData(){
        return liveData;
    }

}

FirestoreQueryLiveData.java

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;

public class FirestoreQueryLiveData extends LiveData<Task<DocumentSnapshot>> {
    private static final String Log_tag = "FirebaseQueryLiveData";
    private final DocumentReference documentReference;
    private final MyValueEventListner listner = new MyValueEventListner();

    public FirestoreQueryLiveData(DocumentReference ref){
        this.documentReference = ref;
    }


    @Override
    protected void onActive(){
        Log.d(Log_tag, "onActive");
        documentReference.get().addOnCompleteListener(listner);
    }

    @Override
    protected void onInactive(){
        Log.d(Log_tag, "onInactive");
        documentReference.get().addOnCompleteListener(listner);
    }

    private class MyValueEventListner implements OnCompleteListener<DocumentSnapshot>{

        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            setValue(task);
        }

    }

}

Add Dependencies

app/build.gradle

implementation 'com.google.firebase:firebase-core:16.0.9'
implementation 'com.google.firebase:firebase-firestore:19.0.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'

If you have any question or suggestions kindly use the comment box or you can contact us directly through our contact page below.

Add a Comment