Firebase Firestore in Android
Useful videos & Blogs :
https://youtu.be/I-MB0nEMLuQ
https://firebase.google.com/docs/firestore/quickstart#java
Dependencies :
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.3.0')
// Declare the dependency for the Cloud Firestore library
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-firestore'
-------------------------------------------------------------------------------------------------
IMPORTNT NOTES :
FireStore is an Upgraded version of RealTime Database & is designed for scale.
It is a document type NO-SQL database unlike the realtime database which is Key-Value based NO-SQL database.
Complex & Hierarchial data is easier to organize and store at scale,which isnt the case with Firebase Realtime database.
You cannot have a Document inside another Document , Or a Collection under a Collection,But you can have SubCollections within documents. This whole structure works great for hierarchial data. The data inside the document is stored as a Key-Value pair.
Example : A Collection named "Users" will contains a Document for each User. Inside which we can also have a subcollection containing documents ,Example : Inside User1 document we can have a subcollection "Games" which can contain document for each game that the user plays.
RealTime Database vs FireStore
You can store data at a specific Location Geographically. There are 2 ways you can store data.
1] Multi-Regional : Data is replicated at multiple regions & places. Reduces DownTime.
2] Regional : Data is stored at one single place only.
Once you set a Location , You cannot change it.
NOTE : Simply assign data to the document inside a collection,if either the document or collection doesnt exist then the firestore will create it for you.
----------------------------------------------------------------------------------------------------------------------------
useful video : https://youtu.be/lVuPWczKOCg
CREATE , WRITE & READ INSIDE COLLECTIONS & DOCUMENTS
When you get a reference of an "existing" document & set their values , it doesnt update the Values, It completely throws the current Document & Creates one with your given values. (SO USE THIS CAREFULLY OR YOU'LL LOOSE DATA)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/read_button"
android:onClick="ReadData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="37dp"
android:layout_marginBottom="71dp"
android:text="Read Data"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="86dp"
android:text="Ready to Code"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/age_edittext" />
<Button
android:id="@+id/save_button"
android:onClick="SaveData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:layout_marginBottom="62dp"
android:text="save data"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/name_edittext"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="37dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Enter Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/age_edittext"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="27dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Enter Age"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_edittext" />
</androidx.constraintlayout.widget.ConstraintLayout>
To know the Source of from where the data is fetched during reading use the below line :
String source = documentSnapshot.getMetadata().hasPendingWrites()? "Local":"Server";
package com.deepesh.myfirestoretutorialapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Source;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
TextView textview1;
Button saveButton, readButton;
EditText name_edittext, age_edittext;
FirebaseFirestore firestore_ref;
// can be used to hold reference to a document.
DocumentReference doc_ref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview1 = findViewById(R.id.textview1);
saveButton = findViewById(R.id.save_button);
readButton = findViewById(R.id.read_button);
name_edittext = findViewById(R.id.name_edittext);
age_edittext = findViewById(R.id.age_edittext);
firestore_ref = FirebaseFirestore.getInstance();
doc_ref = firestore_ref.document("Users/person1");
}
// read data button
public void ReadData(View view) {
Task<DocumentSnapshot> task = doc_ref.get(); // Source.DEFAULT
//
// Firebase by default stores the most recently fetch data from server to device cache.
// If the Internet is not available during fetching , it gets the data from cache.
//
// doc_ref.get(Source.DEFAULT); Gets data from server if internet present else cache (if present)
// doc_ref.get(Source.CACHE); Gets data from Cache only (gives exception if no data in cache)
// doc_ref.get(Source.SERVER); Gets data from server only (gives exception if no internet)
task.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()){
// GET A HASHMAP , THIS WORKS FINE TOO.
// HashMap<String,Object> data_map =
// (HashMap<String, Object>) documentSnapshot.getData();
// String name = (String) data_map.get("name");
// Long age = (Long) data_map.get("age");
String name = documentSnapshot.getString("name");
Long age = documentSnapshot.getLong("age");
String data = "NAME : " + name +"\n"+
"AGE : " + age;
textview1.setText(data);
}else{
textview1.setText("Information doesnt exist !");
}
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("TAG","FAIL TO READ : "+ e.getMessage());
}
});
}
// save data button
public void SaveData(View view) {
String name = name_edittext.getText().toString();
int age = Integer.parseInt(age_edittext.getText().toString());
HashMap<String, Object> person1 = new HashMap<>();
person1.put("name", name);
person1.put("age", age);
// creates collections & documents specified is not present , then
// inserts the values.
Task<Void> task = firestore_ref
.collection("Users")
.document("person1") // document(<No Parameter>) generates random id.
.set(person1);
// firestore_ref.document(Users/person1) - this will work fine too.
task.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
textview1.setText("Data is Inserted");
Toast.makeText(MainActivity.this, "Data Inserted !", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Failed ! to insert Data ", Toast.LENGTH_SHORT).show();
}
}
});
}
}
EXAMPLE 2 :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/username_editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="156dp"
android:ems="10"
android:hint="Username"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/firstname_editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="59dp"
android:ems="10"
android:hint="Firstname"
android:inputType="textPersonName"
app:layout_constraintStart_toStartOf="@+id/username_editText"
app:layout_constraintTop_toBottomOf="@+id/username_editText" />
<EditText
android:id="@+id/lastname_editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:ems="10"
android:hint="Lastname"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/firstname_editText" />
<Button
android:id="@+id/saveData_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="45dp"
android:onClick="SaveData"
android:text="save"
app:layout_constraintBottom_toBottomOf="@+id/readData_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/readData_button" />
<Button
android:id="@+id/readData_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="77dp"
android:layout_marginBottom="86dp"
android:onClick="ReadData"
android:text="read"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
NOTE : If a Document with certain Username already exist & if you try to insert the data inside the document again, then the previous document will get deleted and your current data will be inserted. Careful here ! Else you may loose data.
package com.deepesh.exampleapp4;
import static android.content.ContentValues.TAG;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
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;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
EditText username_editText, firstname_editText, lastname_editText;
DocumentReference documentReference;
final String ROOT_COLLECTION = "Users";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
username_editText = findViewById(R.id.username_editText);
firstname_editText = findViewById(R.id.firstname_editText);
lastname_editText = findViewById(R.id.lastname_editText);
}
public void SaveData(View view) {
String firstname = firstname_editText.getText().toString().trim();
String lastname = lastname_editText.getText().toString().trim();
// We'll use the username as document name
String username = username_editText.getText().toString().trim();
HashMap<String, Object> user_data = new HashMap<>();
user_data.put("firstname", firstname);
user_data.put("lastname", lastname);
// Gets reference to the document, creates one if it doesnt exist.
documentReference = FirebaseFirestore.getInstance().collection(ROOT_COLLECTION).document(username);
// Sets values inside the document
Task<Void> task = documentReference.set(user_data);
task.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: DATA INSERTED SUCESSFULLY");
Toast.makeText(MainActivity.this, "Data Inserted !", Toast.LENGTH_SHORT).show();
} else {
Log.d(TAG, "onComplete: DATA INSERTION FAILED");
Toast.makeText(MainActivity.this, "Failed ! to insert Data ", Toast.LENGTH_SHORT).show();
}
}
});
}
public void ReadData(View view) {
String firstname = firstname_editText.getText().toString().trim();
String lastname = lastname_editText.getText().toString().trim();
// We'll use the username as document name
String username = username_editText.getText().toString().trim();
// Gets reference to the document
documentReference = FirebaseFirestore.getInstance().collection(ROOT_COLLECTION).document(username);
// Gets the data inside document as hashmap
Task<DocumentSnapshot> task = documentReference.get();
// Sucess listener
task.addOnSuccessListener(documentSnapshot -> {
Log.d(TAG, "onSuccess: DATA FETCHING SUCESS");
if (documentSnapshot.exists()) {
HashMap<String, Object> user_data = (HashMap<String, Object>) documentSnapshot.getData();
String firstname1 = user_data.get("firstname").toString();
String lastname1 = user_data.get("lastname").toString();
Log.d(TAG, "onSuccess: FIRSTNAME : " + firstname1 + " LASTNAME : " + lastname1);
} else {
Log.d(TAG, "onSuccess: INFORMATION DOESNT EXIST");
}
});
// Failure listener
task.addOnFailureListener(e -> {
Log.d("TAG","FAIL TO READ : "+ e.getMessage());
});
}
}
---------------------------------------------------------------------------------------------------------------------------
UPDATE DATA IN FIRESTORE
There are 2 ways to update data :
1] SetOptions.merge()
2] Update( )
Difference between two is :
SET( ) updates the values if present at the given location reference else Creates them if not present.
SetOptions.merge( ) Updates the values Only if Present at reference location else Doesnt do anything.
(UI SAME AS ABOVE)
// user clicks update button
public void UpdateData(View view) {
// UPDATE THE NAME VALUE
String name = name_edittext.getText().toString();
HashMap<String, Object> data = new HashMap<>();
data.put("name", name);
// SETOPTIONS.MERGE()
doc_ref.set(data, SetOptions.merge());
// UPDATE()
// doc_ref.update("name",name); // update single value
// doc_ref.update(data); // pass a map of values to change.
}
-------------------------------------------------------------------------------------------------
REALTIME DATEBASE UPDATES FOR DATA CHANGES WITH SnapShotListener( )
You set SnapShotListener to a particular Document , it is called everytime the data in the firestore changes for that place.
package com.deepesh.myfirestoretutorialapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.Source;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
TextView textview1;
Button saveButton, readButton;
EditText name_edittext, age_edittext;
FirebaseFirestore firestore_ref;
// can be used to hold reference to a document.
DocumentReference doc_ref;
ListenerRegistration listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview1 = findViewById(R.id.textview1);
saveButton = findViewById(R.id.save_button);
readButton = findViewById(R.id.read_button);
name_edittext = findViewById(R.id.name_edittext);
age_edittext = findViewById(R.id.age_edittext);
firestore_ref = FirebaseFirestore.getInstance();
doc_ref = firestore_ref.document("Users/person1");
}
@Override
protected void onStart() {
super.onStart();
// REGISTER SNAPSHOT LISTENER
listener = doc_ref.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException exception) {
if (exception != null){
Toast.makeText(MainActivity.this, "ERROR WHILE LOADING DATA", Toast.LENGTH_SHORT).show();
Log.d("TAG", " ERROR : " + exception.getMessage());
}else{
//---------------------------------------
if (documentSnapshot!=null && documentSnapshot.exists()){
// Gives the source from where data is fetched during reading.
String source = documentSnapshot.getMetadata().hasPendingWrites()? "Local":"Server";
String name = documentSnapshot.getString("name");
Long age = documentSnapshot.getLong("age");
String data = "NAME : " + name +"\n"+
"AGE : " + age;
textview1.setText(data);
}else {
Toast.makeText(MainActivity.this, "User Dont exist !", Toast.LENGTH_SHORT).show();
}
//---------------------------------------
}
}
});
}
@Override
protected void onStop() {
super.onStop();
// UNREGISTER SNAPSHOT LISTENER
listener.remove();
}
// read data button
public void ReadData(View view) {
Task<DocumentSnapshot> task = doc_ref.get(Source.SERVER);
task.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()){
String name = documentSnapshot.getString("name");
Long age = documentSnapshot.getLong("age");
String data = "NAME : " + name +"\n"+
"AGE : " + age;
textview1.setText(data);
}else{
textview1.setText("Information doesnt exist !");
}
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("TAG","FAIL TO READ : "+ e.getMessage());
}
});
}
// save data button
public void SaveData(View view) {
String name = name_edittext.getText().toString();
int age = Integer.parseInt(age_edittext.getText().toString());
HashMap<String, Object> person1 = new HashMap<>();
person1.put("name", name);
person1.put("age", age);
Task<Void> task = firestore_ref
.collection("Users")
.document("person1")
.set(person1);
task.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
textview1.setText("Data is Inserted");
Toast.makeText(MainActivity.this, "Data Inserted !", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Failed ! to insert Data ", Toast.LENGTH_SHORT).show();
}
}
});
}
}
-----------------------------------------------------------------------------------------------------------
DELETE KEYS / DOCUMENTS FROM FIRESTORE
(BEAWARE OF HANDLING THE SNAPSHOTLISTENER DURING DELETION ORELSE YOU'LL GET A NULLPOINTER EXCEPTION)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/read_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:layout_marginBottom="22dp"
android:onClick="ReadData"
android:text="Read Data"
app:layout_constraintBottom_toTopOf="@+id/deleteName_button"
app:layout_constraintEnd_toEndOf="parent" />
<ScrollView
android:id="@+id/scrollview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="99dp"
app:layout_constraintEnd_toEndOf="@+id/save_button"
app:layout_constraintStart_toEndOf="@+id/update_button"
app:layout_constraintTop_toBottomOf="@+id/age_edittext">
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ready to Code"
android:textSize="20sp"
tools:layout_editor_absoluteX="141dp"
tools:layout_editor_absoluteY="240dp" />
</ScrollView>
<Button
android:id="@+id/save_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="18dp"
android:layout_marginBottom="20dp"
android:onClick="SaveData"
android:text="save data"
app:layout_constraintBottom_toTopOf="@+id/read_button"
app:layout_constraintEnd_toStartOf="@+id/read_button" />
<EditText
android:id="@+id/name_edittext"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="37dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Enter Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/age_edittext"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="27dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Enter Age"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_edittext" />
<Button
android:id="@+id/update_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="13dp"
android:layout_marginBottom="19dp"
android:onClick="UpdateData"
android:text="Update Name"
app:layout_constraintBottom_toTopOf="@+id/deletePerson_button"
app:layout_constraintEnd_toEndOf="@+id/deletePerson_button" />
<Button
android:id="@+id/deletePerson_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginBottom="31dp"
android:text="Delete Person"
android:onClick="DeletePerson"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/deleteName_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="13dp"
android:layout_marginBottom="28dp"
android:text="Delete name"
android:onClick="DeleteName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.deepesh.myfirestoretutorialapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.SetOptions;
import com.google.firebase.firestore.Source;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
TextView textview1;
Button saveButton, readButton;
EditText name_edittext, age_edittext;
FirebaseFirestore firestore_ref;
// can be used to hold reference to a document.
DocumentReference doc_ref;
ListenerRegistration listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview1 = findViewById(R.id.textview1);
saveButton = findViewById(R.id.save_button);
readButton = findViewById(R.id.read_button);
name_edittext = findViewById(R.id.name_edittext);
age_edittext = findViewById(R.id.age_edittext);
firestore_ref = FirebaseFirestore.getInstance();
doc_ref = firestore_ref.document("Users/person1");
}
@Override
protected void onStart() {
super.onStart();
// REGISTER SNAPSHOT LISTENER
listener = doc_ref.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException exception) {
if (exception != null){
Toast.makeText(MainActivity.this, "ERROR WHILE LOADING DATA", Toast.LENGTH_SHORT).show();
Log.d("TAG", " ERROR : " + exception.getMessage());
}else{
//---------------------------------------
if (documentSnapshot!=null && documentSnapshot.exists()){
// Gives the source from where data is fetched during reading.
String source = documentSnapshot.getMetadata().hasPendingWrites()? "Local":"Server";
String name = documentSnapshot.getString("name");
Long age = documentSnapshot.getLong("age");
String data = "NAME : " + name +"\n"+
"AGE : " + age;
textview1.setText(data);
}else {
Toast.makeText(MainActivity.this, "User Dont exist !", Toast.LENGTH_SHORT).show();
}
//---------------------------------------
}
}
});
}
@Override
protected void onStop() {
super.onStop();
// UNREGISTER SNAPSHOT LISTENER
listener.remove();
}
// read data button
public void ReadData(View view) {
Task<DocumentSnapshot> task = doc_ref.get(Source.SERVER);
task.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()){
String name = documentSnapshot.getString("name");
Long age = documentSnapshot.getLong("age");
String data = "NAME : " + name +"\n"+
"AGE : " + age;
textview1.setText(data);
}else{
textview1.setText("Information doesnt exist !");
}
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("TAG","FAIL TO READ : "+ e.getMessage());
}
});
}
// save data button
public void SaveData(View view) {
String name = name_edittext.getText().toString();
int age = Integer.parseInt(age_edittext.getText().toString());
HashMap<String, Object> person1 = new HashMap<>();
person1.put("name", name);
person1.put("age", age);
Task<Void> task = firestore_ref
.collection("Users")
.document("person1")
.set(person1);
task.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
textview1.setText("Data is Inserted");
Toast.makeText(MainActivity.this, "Data Inserted !", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Failed ! to insert Data ", Toast.LENGTH_SHORT).show();
}
}
});
}
// user clicks update button
public void UpdateData(View view) {
// UPDATE THE NAME VALUE
String name = name_edittext.getText().toString();
HashMap<String, Object> data = new HashMap<>();
data.put("name", name);
doc_ref.update(data); // pass a map of values to change.
}
// user clicks on deletePerson button
public void DeletePerson(View view) {
// Deletes the entire Document
doc_ref.delete();
}
// user clicks on deleteName button
public void DeleteName(View view) {
// HashMap<String,Object> dataToDelete = new HashMap<>();
// dataToDelete.put("name",FieldValue.delete());
// dataToDelete.put("age",FieldValue.delete());
// doc_ref.update(dataToDelete);
// Delete specified key value from the entire document.
doc_ref.update("name", FieldValue.delete());
}
}
---------------------------------------------------------------------------------------------------------
useful video : https://youtu.be/m7YvtJuKIhY
INSERT OBJECTS INSIDE THE FIRESTORE
If the number of Key values is large then its viable to create modal class objects and insert them into firebase . This makes easy handling of keys , since we dont have to mention or maintain the keys for every field stored inside a document.
(UI SAME AS ABOVE)
package com.deepesh.myfirestoretutorialapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.Source;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
TextView textview1;
Button saveButton, readButton;
EditText name_edittext, age_edittext;
FirebaseFirestore firestore_ref;
// can be used to hold reference to a document.
DocumentReference doc_ref;
ListenerRegistration listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview1 = findViewById(R.id.textview1);
saveButton = findViewById(R.id.save_button);
readButton = findViewById(R.id.read_button);
name_edittext = findViewById(R.id.name_edittext);
age_edittext = findViewById(R.id.age_edittext);
firestore_ref = FirebaseFirestore.getInstance();
doc_ref = firestore_ref.document("Users/person1");
}
@Override
protected void onStart() {
super.onStart();
// REGISTER SNAPSHOT LISTENER
listener = doc_ref.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException exception) {
if (exception != null){
Toast.makeText(MainActivity.this, "ERROR WHILE LOADING DATA", Toast.LENGTH_SHORT).show();
Log.d("TAG", " ERROR : " + exception.getMessage());
}else{
//---------------------------------------
if (documentSnapshot!=null && documentSnapshot.exists()){
// Gives the source from where data is fetched during reading.
String source = documentSnapshot.getMetadata().hasPendingWrites()? "Local":"Server";
Person person1 = documentSnapshot.toObject(Person.class);
String data = "NAME : " + person1.getName() +"\n"+
"AGE : " + person1.getAge();
textview1.setText(data);
}else {
Toast.makeText(MainActivity.this, "User Dont exist !", Toast.LENGTH_SHORT).show();
}
//---------------------------------------
}
}
});
}
@Override
protected void onStop() {
super.onStop();
// UNREGISTER SNAPSHOT LISTENER
listener.remove();
}
// read data button
public void ReadData(View view) {
Task<DocumentSnapshot> task = doc_ref.get(Source.SERVER);
task.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()){
Person person1 = documentSnapshot.toObject(Person.class);
String data = "NAME : " + person1.getName() +"\n"+
"AGE : " + person1.getAge();
textview1.setText(data);
}else{
textview1.setText("Information doesnt exist !");
}
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("TAG","FAIL TO READ : "+ e.getMessage());
}
});
}
// save data button
public void SaveData(View view) {
String name = name_edittext.getText().toString();
int age = Integer.parseInt(age_edittext.getText().toString());
Person person1 = new Person(name,age);
Task<Void> task = firestore_ref
.collection("Users")
.document("person1")
.set(person1);
task.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
textview1.setText("Data is Inserted");
Toast.makeText(MainActivity.this, "Data Inserted !", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Failed ! to insert Data ", Toast.LENGTH_SHORT).show();
}
}
});
}
// user clicks update button
public void UpdateData(View view) {
// UPDATE THE NAME VALUE
String name = name_edittext.getText().toString();
HashMap<String, Object> data = new HashMap<>();
data.put("name", name);
doc_ref.update(data); // pass a map of values to change.
}
// user clicks on deletePerson button
public void DeletePerson(View view) {
// Deletes the entire Document
doc_ref.delete();
}
// user clicks on deleteName button
public void DeleteName(View view) {
// HashMap<String,Object> dataToDelete = new HashMap<>();
// dataToDelete.put("name",FieldValue.delete());
// dataToDelete.put("age",FieldValue.delete());
// doc_ref.update(dataToDelete);
// Delete specified key value from the entire document.
doc_ref.update("name", FieldValue.delete());
}
}
Modal class
package com.deepesh.myfirestoretutorialapp;
public class Person {
String name;
int age;
public Person() {
// Used by the system
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
------------------------------------------------------------------------------------------------------













Comments
Post a Comment