You can store your data in the cloud using Cloud Firestore. You can sync it across all your devices or share them with multiple users. It comes with robust client libraries, full support for offline mode. Your app will continue to work just fine whether you’re connected or not. A comprehensive set of security rules to help you manage access and an easy-to-use data browsing tool. It also lets you structure your data in ways that make sense to you thanks to its powerful querying and fetching capabilities.

Cloud Firestore works in real timeautomatically fetching changes from your database as they happen, or you can request and fetch data manually.It’s completely up to you.

Getting Started with Cloud Firestore on Android


So I’m working a little app here that lets me store a thought. My App consists of an EditText where I can enter my thought and then the second one here where I can enter the publisher’s name and  then I have Publish button where we’re gonna save whatever thought our user has entered into the cloud so later we’ll load whatever data our users saved to the cloud and display it with a big Listview or something

Enable Firestore in Firebase


In order access to Firestore you need to enable Firestore in Firebase Console. Enable Firestore

 

Add Firebase to your Android project


Create a Firebase project in the firebase console and configure the Google services plug-in with JSON file. Add Firebase to your Android project

Firestore is a Document Database


Firestore store your data in a big tree like structure kind of like the original real-time database but everything is placed into documents and collections. For more about a document database, read this post. Firestore DocumentAdd Firestore Dependency to your app


Let’s start building so first thing you need to make sure you have Firestore installed. Into app.gradle file add Firestore.

dependencies {
    ....
    compile 'com.google.firebase:firebase-firestore:16.0.0'
}

In main activity here I’m gonna head on down to my publishThought call.

public void publishThought(View view) {
        final String name = nameView.getText().toString().trim();
        String thought = thoughtView.getText().toString().trim();
        .....
}

Cloud Firestore also supports writing your own Java objects with custom classes. Cloud Firestore will internally convert the objects to supported data types.Each custom class must have a public constructor that takes no arguments. In addition, the class must include a public getter for each property. Now you just need to save this to the cloud and to do that you need to specify in which document you want to put this data so you do that through an object known as a DocumentReference let’s initialized it up.

DocumentReference docRef;
....
docRef = FirebaseFirestore.getInstance().document("thought/lifeThought");

I pass along a slash-separated string as our path so in our case, the path would be “thought/lifeThought Just remember that in your path you’re always going to be alternating between collections documents collection document and so on.Firestore Database Path Now that I’ve specified my document. In my publishThought() method where I’m going to call set on the document reference and that will take in the data. I created above as the contents of my document this call will replace my current document if it exists and created if it doesn’t it also conveniently create the sample data collection too so I don’t need to worry about that not existing now I’m going to chain on an addOnSuccessListener like so where we can print a debug message. And then we can add an addOnFailureListener listener where we can print out any error messages.

public void publishThought(View view) {
       ....
   if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(thought)) {
         Thought th = new Thought(thought, name);
         docRef.collection(PUBLIC_THOUGHT).add(th)
             .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                  @Override
                  public void onSuccess(DocumentReference documentReference) {
                       Log.d(TAG, "DocumentSnapshot written with ID: " + documentReference.getId());
                       nameView.setText("");
                       thoughtView.setText("");
                  }
              })
             .addOnFailureListener(new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                   Log.w(TAG, "Error adding document", e);
              }
       });
   }

For those of you who are all about fewer listener in your call, you could also handle this with a single OnCompleteListener like and then just check in here to see if your task is successful either way works and honestly it’s just really up to you which method you prefer.

Error on Document Writing com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.

Just like the real-time database cloud, Firestore implementation contains a set of security rules that determine whether or not a certain action will be permitted.By default they’re set up that nobody can read or write to the database.I’m willing to share with each particular user.So I’m just going to do a bit a hack here and make my sample data documents open to the public. Set Firestore rules I’ll select my project go to database selection and then make sure I select cloud Firestore for my list of database options then I will click the rules tab and then I’m going to add these lines here to allows reading and writing to anything that’s part of my sample data collection now this a pretty terrible idea from a security perspective but at least I’ve contained the damage to just what’s in my sample data collection so I’ll publish that and we are done. So I’m going to start up my app, and I am going to enter thought in the text field and I hit publish button. Firestore Database on android I can verify this by going back to the Firebase console we’ll select the data tab and then I can look at our data collection find our document and sure enough look likes we’ve saved our inspiring thought to the world. Firebase Cloud Firestore Database

Get Data with Cloud Firestore


We need to show our users this inspirational thought by grabbing that data from the cloud and populating in some kind of list view with it now like the real-time database cloud Firestore lets me listen to changes in the database and update my app in real time. So let’s create a Thought List I ’m gonna add a Recyclerview in the middle of my screen that has a TextView where I can display the thought and publisher name. I already have my document reference.

Perform Simple Query in Cloud Firestore


Cloud Firestore provides powerful query functionality for specifying which documents you want to retrieve from a collection. These queries can also be used with either get() or addSnapshotListener().

private Query query;
....
query = docRef.collection(PUBLIC_THOUGHT).orderBy("timestamp", Query.Direction.DESCENDING)
                .limit(LIMIT);

Get Realtime Updates with Cloud Firestore


You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

public void startListening() {
    if (mQuery != null && mRegistration == null) {
          mRegistration = mQuery.addSnapshotListener(this);
    }
}
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
    if (e != null) {
          Log.w(TAG, "onEvent:error", e);
          onError(e);
          return;
    }
    // Dispatch the event
    Log.d(TAG, "onEvent:numChanges:" + documentSnapshots.getDocumentChanges().size());
    for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
          switch (change.getType()) {
             case ADDED:
                 onDocumentAdded(change);
                 break;
             case MODIFIED:
                  onDocumentModified(change);
                  break;
              case REMOVED:
                  onDocumentRemoved(change);
                  break;
       }
    }
}

When I publish thought now my callback is getting called twice once for the change in my local cache and then once on the server.This is because of an important feature called latency compensation.

 

Download this project from GitHub

Related Post

Firestore Document Database Data Model.

Firestore Security With Firebase Authentication