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

Popular posts from this blog

React Js + React-Redux (part-2)

React Js + CSS Styling + React Router (part-1)

ViteJS (Module Bundlers, Build Tools)