C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Read and Write in FirestoreIn 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 FirestoreFor 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:
Set a DocumentWe 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 Data TypesWe 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 ObjectsWe 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 Reading data from Firestoredb.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.
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 Objectsval docRef=db.collection("cities").document("Bj") docRef.get().addonSuccessListener{ documentSnapshot -> val city=documentSnapshot.toObject(City::class.java) } Getting multiple documents from a collectionWe 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 collectiondb.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 ExtensionIf 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' Kotlinval Firestore=FirebaseFirestore.getInstance() val anotherFirestore=FirebaseFirestore.getInstance(FirebaseApp.getInstance("myApp")) Kotlin+KTXval Firestore=Firebase.firestore val anotherFirestore=Firebase.firestore(Firebase.app("myApp")) Conversion of DocumentSnapshot Field to a plain old Java object1) 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 Or val snapshot: DocumentSnapshot=... val myObject=snapshot.toObject Conversion of QuerySnapshot to a plain old Java object1) 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 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:
Next TopicUpdate and Delete in Firestore
|