<!-- Generated from the rendered page by scripts/write-llm-mirrors.mjs. Do not edit by hand. -->
Canonical: https://molo17.com/blog/firebase-authentication-and-cloud-firestore-in-android-part-2/
Markdown mirror: https://molo17.com/blog/firebase-authentication-and-cloud-firestore-in-android-part-2/index.md
Title: Firebase Authentication and Firebase Cloud Firestore in Android - Part 2
Description: Part 2 of the series on how to combine Firebase Authentication and Cloud Firestore in an Android project, in which you will see how to use Cloud Firestore.

[← All articles](/blog/)

Article

# Combined use of Firebase Authentication and Firebase Cloud Firestore in Android – Part 2

13 Apr 2019  [Knowledge sharing](/blog/?category=knowledge-sharing)  6 min read

As done in the first part, I’ve got a question for you! ? There are a lot of possibilities to implement an Android app with database features, but what \[…\]

![](https://molo17.com/wp-content/uploads/2023/03/accurate-on-time-data.png)

As done [in the first part](\"https://molo17.com/2019/03/combined-use-of-firebase-authentication-firebase-cloud-firestore-on-android-part-1/\"), I’ve got a question for you! ? There are a lot of possibilities to implement an Android app with database features, but what do you think if I told you that there’s a method with which you can add a database syncable across all the platform and also handle data from a web page? Yes, you\\’re right… Google and [Firebase](\"https://jelvix.com/blog/what-is-firebase\") with Cloud Firestore!?

I\\’m talking about Firebase Cloud Firestore. Cloud Firestore is a flexible, scalable NoSQL cloud database with the capabilities to sync data across all attached platform. In addition offer offline support both for mobile and for web that work regardless of network latency or Internet connectivity.

The Cloud Firestore data model supports flexible, hierarchical data structures. Store your data in documents, organized into collections. Documents support many different [data types](\"https://firebase.google.com/docs/firestore/manage-data/data-types\"), from simple strings and numbers, to complex, nested objects and subcollections.

**Tip**: If you are totally new in non-relational database model, suggest you to give a look to the official [Firebase Cloud Firestore documentation](\"https://firebase.google.com/docs/firestore/data-model\") regarding the database model.

Querying is expressive, efficient, and flexible. You can retrieve data at the document level without needing to retrieve the entire collection, or any nested subcollections.

In this second part you will learn how to read/write the role of an employee from Cloud Firestore in your Android app.

## **Enable Firebase Cloud Firestore**

In order to enable Cloud Firestore open the Firebase Console and select the project created in the first part of the tutorial.

### Cloud Firestore Database creation

Now click on **Database** section and you will see the top of the page like this:

![\\"Firebase](\"https://lh6.googleusercontent.com/2Ae6y9XvS9D0SI5kCMW9PBL4bkGht7Tz8U05az936sE1U951BjakrEugSXEbGm9kceeKJnAYJ5bPNWYKPHX2bqi0I8zZZbCRMInf8pSuU5V6_36LQv2E29u59duQ4bWOmM0cXGg\")

Cloud Firestore – Create a database

Then click on **Create Database**.

You can now choose if you want to keep the database public or set usage rules, those rules are editable in a second time. Choose **Start in locked mode**, click on **Enable** and start inserting data in your database clicking on **Add collection**.

## Set the Firestore collection ID

Firebase will present you a mask like:

![\\"Firebase](\"https://lh3.googleusercontent.com/G_q09WquUfGcf2MicwdFwK23uaN1gUzqMxJsZeCvo-ThqUEreb5paqLIA8rTC0YPZxEPUCoXHzxb_N8FNVbB7C9SWSy3fr-AdBa1Qtwf3-63Nwa96c-RYVMoU5dan-7qDtnmdtM\")

Start a collection dialog: Set collection ID

The **_Collection ID_** is the main collection name (like table name in SQL database) then in our case we can insert **_roles_**_._

### Add the first document to Cloud Firestore

After the **_Collection ID_** you have to insert the **_Document ID_**. This will be the name of the role (e.g. _administrator_), then insert the role name in the **_Document ID_** box. Finally, as you can see in the picture below, it’s already possible to insert Document data using **_Field._**

![\\"Firebase](\"https://lh4.googleusercontent.com/S5gtZUqVKdYiRgt3quAwHDBhJzHzq63i1_e090EhEp0oAn8L90pKuY2xfSVRqaz2zLfj2ivwiS9nFv-N4lnqO_b0TAbZ-pCSRS4VRRvmmCJy9Fr1korH_0vY_GGm9lKuuGJ3XIE\")

Start a collection dialog: Add first document

In **_Field_** box insert **_users_** and select _array_ as field type, finally insert all the _UIDs_ you want for _administrator_ role and once finished click on save.

If you want insert some other roles you have to click on **_Add document_** in the **_roles_** column and then start adding the users list as described above.

The final structure that will be obtained is similar to this:

![\\"Firebase](\"https://lh4.googleusercontent.com/Xh8AZyT9l9pH0cfK26FNF7vFH647mZETp7hlaSRQ9GiBcZTuEUHq6NYK8x7ejJa_n1dywhPu1JTBHNsDQjKhxZ1qpI-8lXZKkLTZRHkBg2VP7bDDmwY17LytN2or56Zt1cCvS7I\")

Firebase Cloud Firestore database overview

### Improve security to your Cloud Firestore database

**_Tip_**: To improve security of your database go to the **Rules** tab. In our example, we want to allow read/write to authenticated user then we have to use these security rules:

allow read: if request.auth.uid != null;
allow write: if request.auth.uid != null;

Like in the image above.

![\\"\\"/](\"https://lh4.googleusercontent.com/67onOq8nIKnGTefDHL7GDw0brv09UuH6znObzCA-r8KvEHz9a0fIf-eJtVrxbvIVBvV6XW-qC6ZIEufat23eaYC2tyDgMRy3amLAIwaG_968ooe444neFkqF86kcWUiJvUhB0CM\")

Great you’re ready to use Cloud Firestore in your Android app! Hurray! ?

## **Coding Time** ?

First thing to do is add the Cloud Firestore dependency to Gradle with

implementation \\'com.google.firebase:firebase-firestore:18.0.1\\' 

then _Sync Gradle_ and get ready to code! ?

### Let’s start from read operation!

In the previous part we’ve implemented the **_MainActivity_** that we will use to retrieve and show the role of the employee. We can create a method **_getUserRoleWithQuery_** which will retrieve data from Firebase Cloud Firestore using Cloud Firestore Queries.

First of all you can add to the **_BaseActivity_** a variable used to access the current user info for example the UID, like:

protected val currentUser: FirebaseUser?
    get() = auth.currentUser

Then in your _**MainActivity**_ add the method _**getUserRoleWithQuery**_:

currentUser?.uid?.let { uid ->
   firestore
       .collection(\\"roles\\")
       .whereArrayContains(\\"users\\", uid)
       .get()
       .addOnCompleteListener { task ->
           task.result?.run {
               when (documents.size) {
                   1 -> {
                       val role  = documents\[0\].reference.path.split(\\"/\\")\[1\]
                       user\_role\_text\_view.text = \\"Your role is: $role\\"
                   }
                   else -> showError()
               }
           }
       }
       .addOnFailureListener { showError() }
} ?: showError()

#### Notes

-   **_firestore_** is an instance of **FirebaseFirestore** (**_FirebaseFirestore.getInstance()_**).
-   Method **_collection_** identify where to query for data.
-   Method **_whereArrayContains_** query for an array which contains a specific value (for example search in “**_users_**” array our users **_UID_**).
-   **_documents\[0\].reference.path_** identify the role path (for example **_roles/administrator_**) so we split this path to get only the role name.
-   We\\’re asserting that a user can assume only a role so if documents size is greater than one, something went wrong with the call or the currentUser is null i show an error.

### Let’s finish with write operation!

Now your app can read the role from your database populated from Firebase Web page. However, why stop here if you can handle also the creation of a new user/role in your database directly from your app?

Before all you have to add three extensions and the onComplete listener implementation (for authentication create user method) in your SignInActivity so you can handle all the new user register flow.

The first extensions i’ve added in the example is **_Task<Void>.addCompleteListener()_** used to add the complete listener for add/update user request. It’s very simple and the result of my implementation is:

private fun Task<Void>.addCompleteListener() {
   addOnCompleteListener {
       MainActivity.newInstance(this@SingInActivity).let(::startActivity)
       finish()
   }.addOnFailureListener {
       FirebaseAuth.getInstance().signOut()
       Toast.makeText(baseContext, \\"Error saving user\\", Toast.LENGTH\_SHORT).show()
   }
}

#### User add method

The second extensions i’ve added is**_DocumentReference.addNewUser(uid: String)_** so, when a role doesn’t exist in our database, we can add it with related user. In order to add both the role and the related user you have to use the **_set_** method present in the _DocumentReference_ class which we are extending:

private fun DocumentReference.addNewUser(uid: String) {
   val userMap = HashMap<String, MutableList<String>>()
   userMap\[\\"users\\"\] = mutableListOf(uid)
   set(userMap).addCompleteListener()
}

The **_set_** method accept a map as params then we create an _HashMap_ where we store the array of user for the role. As you can see in the map we store a list of **_uid_** associated to the **_users_** key used by Cloud Firestore to create and name your array populated with your list.

##### Users array update

Third and last extension is **_DocumentReference.updateArray(uid: String)_** used to add a new user to the **_users_** array when inserted role already exist. To do so you can use the **_update_** method of _DocumentReference_:

private fun DocumentReference.updateArray(uid: String) {
   update(\\"users\\", FieldValue.arrayUnion(uid)).addCompleteListener()
}

In this case you will use the update method that accept the array name you want to update and type of operation you are executing. As we want to keep the users already added to our array we _must_ use the **_FieldValue.arrayUnion_**. As a result of this operation, Cloud Firestore will add new uids in array maintaining old users uid.

Finally you have to implement your onComplete listener. Most important thing here is check if inserted role exist in your Cloud Firestore database or not and select the correct extension to call like:

currentUser?.uid?.let { uid ->
   val role = roles\_edit\_text.text.toString()

   firestore
       .collection(\\"roles\\")
       .document(role)
       .get()
       .addOnSuccessListener { docSnapshot ->
           if (docSnapshot.exists()) {
               docSnapshot.reference.updateArray(uid)
           } else {
               docSnapshot.reference.addNewUser(uid)
           }
       }
}

Now you have all the required method to start the registration flow using **_FirebaseAuth._**

### Final Step!

Last method to use is **_createUserWithEmailAndPassword_** of FirebaseAuth that will register effectively new user on Firebase. Hence you can call this method like:

auth.createUserWithEmailAndPassword(
   email\_edit\_text.text.toString(),
   password\_edit\_text.text.toString()
).addOnCompleteListener(this)

## **Conclusions**: Firebase Auth plus Cloud Firestore

Great, all done! You have now a fully working app with authentication and database linked together.

Our journey exploring Firebase Authentication and Cloud Firestore is now over, thanks for reading, and stay tuned for more articles!?

You can find all the code in this [Github](\"https://github.com/MOLO17/AuthFirestorePOC\") repository!

[← Older article A trip into Kotlin Multiplatform Projects – Part 3: an every day app](/blog/kotlin-a-trip-into-multiplatform-projects-part-3/) [Newer article → How I built a Slack bot for our lunch break](/blog/how-i-built-a-slack-bot-for-our-lunch-break/)

## Keep reading

1.  [Knowledge sharing #5 Discover Couchbase: Couchbase Peer-to-Peer Sync The Discover Couchbase section continues with the fifth chapter, which deals in particular with Peer-to-Peer Sync. In the previous article we discovered how to make an app using the \[…\] 6 Mar 2020](/blog/couchbase-peer-to-peer-sync-en/)
2.  [Knowledge sharing #4 Discover Couchbase: your first app with Couchbase Lite In the previous articles we had a first look at Couchbase Lite and we discovered how to integrate it into a mobile app. Moreover, we got aware of Couchbase \[…\] 7 Feb 2020](/blog/your-first-app-with-couchbase-lite/)
3.  [Knowledge sharing TCP/IP Network for Programmers: Part One The first thing I want to let you know is that for years I have been dealing with game development, rather than business software. However, over the years, the \[…\] 31 May 2019](/blog/tcp-ip-network-for-programmers-part-one/)

[Back to all articles](/blog/) [More in Knowledge sharing →](/blog/?category=knowledge-sharing)
