TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

Firebase Read and Write in Firestore

Firebase Read and Write in Firestore with What is Firebase, Features, Android Studio, Assistance, Adding Firebase to App, Installation, Data, Firebase Arrays, Event Types, Firebase Queries, Firebase Security etc.

<< Back to FIREBASE

Read and Write in Firestore

In this section, we will learn how to read and write can be done in Firebase Firestore. Previously, we created an android application and added Firebase with it. We have already implemented all the required libraries and plugins. There is already a Firestore database that we have created before.

Writing data into Firestore

For writing data, we have to retrieve an instance of our database using getInstance() and reference the location where we want to write to. We will access the cloud Firestore instance from our activity.

val db=FirebaseFirestore.getInstance()

As we already know, data is stored in documents, and these documents are stored in collections. So, we will create collections and documents implicitly. When we add data for the first time to the document, the collection is automatically going to be created. Let's see an example of adding a map into the collection.

//Creating a new user with a first and last name
val user=hashMapOff(
	"first" to"Shubham",
	"last" to "Rastogi"
	"born" to 1815
)
//Adding a new document with generated ID
db.collection("users").add(user).addOnSuccessListener { documentReference ->
	Log.w(TAG,"DocumentSnapshot added with ID:${documentReference.id}")
}
.addOnFailureListener{e ->
	Log.w(TAG,"Error adding document",e)
}

There are several ways to write data into Cloud Firestore, which are as follows:

  1. In a first way, we set the data of a document within a collection, explicitly specifying a document identifier.
  2. We can write data into the database by adding a new document to a collection. The Cloud Firestore automatically generates the document identifier.
  3. We can write data into the database by creating an empty document with an automatically generated identifier. The data will be assigned to it later.

Set a Document

We use the set() method for creating or overwriting a single document. When we use set() method for creating a document, we must specify an ID for the document to create.

db.collection("cities").document("new-city-id").set(data)
val city = hashMapOf(
	"name" to "Noida"
	"state" to "UP"
	"country" to "India"
)
db.collection("cities").document("LA").set(city)

When we use set() to create a document, it is more convenient to let Cloud Firestore auto-generate an ID for us(add()).

// Adding a new document with a generated id
val data=hashMapOf(
	"name" to "UP"
	"country" to "India"
)
db.collection("cities").add(data)
	.addOnSuccessListener{
		documentReference -> Log.d(TAG,"DocumentSnapshot written with ID:${documentReference.id}")
}
.addOnFailureListener{
	e->Log.w(TAG,"Error adding document",e)
}

It can also be useful to create a document reference with auto-generated ID, then use the reference later(doc()).

val data=HashMap()
val newCityRef=db.collection("cities").document()
//Later...
newCityRef.set(data)

Data Types

We can write a variety of data types and objects inside a document.

val docData=hashMapOf(
	"stringExample" to "JavaTpoint",
	"booleanExample" to true,
	"numberExample" to 3.14159265,
	"dateExample" to Timestamp(Date()),
	"listExample" to arrayListOf(1, 2, 3),
	"nullExample" to null
)
val nestedData=hashMapOf(
	"a" to 5,
	"b" to true
)
docData["objectExample"]=nestedData
db.collection("data").document("one")
	.set(docData)
	.addOnSuccessListener{Log.d(Tag,"DocumentSnapshot successfullyt written")}
	.addOnFailureListener{e->Log.w(TAG,"Error writing document",e)}

Custom Objects

We can write our own java objects with custom classes. These custom classes internally convert the objects into supported datatypes. Each column class must have a public constructor which takes no arguments and the class must have a public getter for each property.

data class City(
	val name:String?=null,
	val state:String?=null,
val country:String?=null, 
val isCapital:Boolean?=null,
val population:Long?=null,
val regions:List?=null
)
val city=City("Noida","UP","India",false,5000000L,listOf("west_coast","social"))
db.collection("cities").document("LA").set(city)

Reading data from Firestore

db.collection("users")
	.get().addOnSuccessListener{result->
		for(document in result){
			Log.d(TAG,"${document.id}=>${document.data}")
		}
	}
	.addOnFailureListener{exception->
		Log.w(TAG,"Error getting documents.",exception)
}

There are two ways for retrieving data, which is stored in Cloud Firestore.

  1. Calling a method to get the data.
  2. Setting a listener for receiving data changes events. We send an initial snapshot of the data, and then another snapshot is sent when the document changes.

Both of these methods are used with documents, collections of documents, or the result of queries. Let's take an example in which we fill the database with some data about cities.

val data1=hashMapOf(
	"name" to "noida"
	"state" to "UP"
	"country" to "USA"
	"capital" to false,
	"population" to 860000,
	"regions" to listOf("hinduism","Muslims")
)
cities.document("SF").set(data1)

Using Custom Objects

val docRef=db.collection("cities").document("Bj")
docRef.get().addonSuccessListener{
	documentSnapshot ->
		val city=documentSnapshot.toObject(City::class.java)
}

Getting multiple documents from a collection

We can also retrieve multiple documents by querying documents in a collection. We can use where() to query for all of the documents which meets a certain condition and then use get() to retrieve the results.

db.collection("cities").whereEqualTo("capital",true).get()
	.addOnSuccessListener{ documents ->
		for(document in documents){
			Log.d(TAG,"${document.id}=>${document.data}")
		}
	}
	.addOnFailureListener{exception ->
		Log.w(TAG,"Error getting documents:",exception)
}

Getting multiple documents from a collection

db.collection("cities").get()
	.addOnSuccessListener{ documents ->
		for(document in documents){
			Log.d(TAG,"${document.id}=>${document.data}")
		}
	}
	.addOnFailureListener{exception ->
		Log.w(TAG,"Error getting documents:",exception)
}

Using Cloud Firestore with Kotlin Extension

If we want to use the Cloud Firestore Android SDK with Kotlin Extensions, we have to add the following library in our app's buid.gradle file:

We have to ensure that there is the latest version of maven.google.com. This library transitively includes the firebase-Firestore library.

Implementation 'com.google.firebase: firebase-firestore-ktx: 18.2.0'  

Kotlin

val Firestore=FirebaseFirestore.getInstance()
val anotherFirestore=FirebaseFirestore.getInstance(FirebaseApp.getInstance("myApp"))

Kotlin+KTX

val Firestore=Firebase.firestore
val anotherFirestore=Firebase.firestore(Firebase.app("myApp")) 

Conversion of DocumentSnapshot Field to a plain old Java object

1) Kotlin

val snapshot: DocumentSnapshot=...
val myObject=snapshot.get("fieldPath",MyClass::class.java)

Or

val snapshot: DocumentSnapshot=...
val myObject=snapshot.toObject(MyClass::class.java)

2) Kotlin+KTX

val snapshot: DocumentSnapshot=...
val myObject=snapshot.get("fieldPath")

Or

val snapshot: DocumentSnapshot=...
val myObject=snapshot.toObject()

Conversion of QuerySnapshot to a plain old Java object

1) Kotlin

val snapshot: QuerySnapshot=...
val myObject=snapshot.toObject(MyClass::class.java)

2) Kotlin+KTX

val snapshot: QuerySnapshot=...
val myObject=snapshot.toObject()

Example:

We are implementing an android application. It is a user logging and registration application that has three xml files and four Kotlin files. The activity_main.xml is used for the registration page. The activity_signing.xml is used for login, and activity_welcome.xml is used for data retrieving from the database. Similarly, there is four Kotlin file, i.e., MainActivity, Signing, welcome, and User.

When the users register themselves, they are added into the firebase console user section, and the data corresponding to them is stored in the database. The signing functionality is the same as we have done in our authentication section. When a user successfully registers or sign-up, he will switch to the welcome page where he will find his data.

activity_main.xml, activity_signing, and activity_welcome

Read and Write in Firestore

MainActivity.kt

package com.example.firestoreexample

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private var mAuth: FirebaseAuth?=null
    private var mFirebaseDatabaseInstances:FirebaseFirestore?=null

    private var userId:String?=null
    private var emailAddress:String?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Get Firebase Instances
        mAuth=FirebaseAuth.getInstance()
        mFirebaseDatabaseInstances= FirebaseFirestore.getInstance()

        //if already logged in go to sign in screen
        if(mAuth!!.currentUser!=null){
            startActivity(Intent(this,welcome::class.java))
            finish()
        }
    }

    fun onLoginClicked(view: View) {
        startActivity(Intent(this,signing::class.java))
        finish()
    }
    fun onRegisterClicked(view: View) {
        if(TextUtils.isEmpty(username.text.toString())){
            Toast.makeText(applicationContext,"Enter Username!",Toast.LENGTH_LONG).show()
        }
        if(TextUtils.isEmpty(email.text.toString())){
            Toast.makeText(applicationContext,"Enter email address!",Toast.LENGTH_LONG).show()
        }
        if(TextUtils.isEmpty(password.text.toString())){
            Toast.makeText(applicationContext,"Enter password!",Toast.LENGTH_LONG).show()
        }
        if(password.text.toString().length<6){
            Toast.makeText(applicationContext,"Password is too short",Toast.LENGTH_LONG).show()
        }

        progressBar!!.visibility=View.VISIBLE

        //create user
        mAuth!!.createUserWithEmailAndPassword(email.text.toString(),password.text.toString())
            .addOnCompleteListener(this){task ->
                Toast.makeText(this,"createUserWithEmail:onComplete"+task.isSuccessful,Toast.LENGTH_SHORT).show()
                progressBar.visibility=View.GONE

                if(task.isSuccessful){

                    val user=FirebaseAuth.getInstance().currentUser

                    //add username, email to database
                    userId=user!!.uid
                    emailAddress=user.email

                    val myUser=user(username.text.toString(),emailAddress!!)

                    mFirebaseDatabaseInstances?.collection("users")?.document(userId!!)?.set(myUser)

                    startActivity(Intent(this,welcome::class.java))
                    finish()
                }else{
                    Toast.makeText(this,"Authentication Failed"+task.exception,Toast.LENGTH_SHORT).show()
                    Log.e("MyTag",task.exception.toString())
                }
            }
    }
}

welcome.kt

package com.example.firestoreexample

import android.content.Intent
import android.nfc.Tag
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.constraintlayout.solver.widgets.Snapshot
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.email
import kotlinx.android.synthetic.main.activity_main.username
import kotlinx.android.synthetic.main.activity_welcome.*

class welcome : AppCompatActivity() {

    private var mFirebaseDatabaseInstance:FirebaseFirestore?=null
    private var userId:String?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_welcome)

        mFirebaseDatabaseInstance= FirebaseFirestore.getInstance()

        val user=FirebaseAuth.getInstance().currentUser

        //add it only if it is not saved to database
        if (user != null) {
            userId=user.uid
            Log.e(TAG,"User data is null")
        }
        getDataOneTime()
    }
    private fun getDataOneTime(){

        //getting the data onetime
        val docRef=mFirebaseDatabaseInstance?.collection("users")?.document(userId!!)

        docRef?.get()?.addOnSuccessListener { documentSnapshot ->
            val user=documentSnapshot.toObject(user::class.java)

            Log.e(TAG,"user data is changed"+user?.name+", "+user?.email)

            //Display newly updated name and email
            txt_user.setText(user?.name+", "+user?.email)

            //Clear edit text
            email.setText(user?.email)
            username.setText(user?.name)
        }
    }
    fun onLogout(view: View) {
        FirebaseAuth.getInstance().signOut()
        startActivity(Intent(this, MainActivity::class.java))
    }
    companion object{
        private val TAG=welcome::class.java.simpleName
    }
}

Output:

Read and Write in Firestore
Read and Write in Firestore




Related Links:


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf