In the previous article, we have seen on How to Add Data to Firebase Firestore in Android, How to Read the data from Firebase Firestore in Android. Now we will see How to Update this added data inside our Firebase Firestore. Now we will move towards the implementation of this updating data in Android Firebase.
What we are going to build in this article?
We will be creating a similar screen as we were creating for adding the data and inside this screen, we will be updating our data inside our Firebase Firestore and that data will also be updated inside our app.
Step by Step Implementation
Step 1: Creating a new Activity for updating the data
For creating a new Activity navigate to the app > res > layout > Right-Click on it and click on New > then click on Empty Activity to create a new Activity and we will name it as UpdateCourse. After creating a new Activity navigate to the app > res > layout > activity_update_course.xml and add the below code to it.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" tools:context = ".UpdateCourse" > <!--Edittext for getting course Name--> < EditText android:id = "@+id/idEdtCourseName" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_marginStart = "10dp" android:layout_marginTop = "20dp" android:layout_marginEnd = "10dp" android:hint = "Course Name" android:importantForAutofill = "no" android:inputType = "text" /> <!--Edittext for getting course Duration--> < EditText android:id = "@+id/idEdtCourseDuration" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_marginStart = "10dp" android:layout_marginTop = "20dp" android:layout_marginEnd = "10dp" android:hint = "Course Duration in min" android:importantForAutofill = "no" android:inputType = "time" /> <!--Edittext for getting course Description--> < EditText android:id = "@+id/idEdtCourseDescription" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_marginStart = "10dp" android:layout_marginTop = "20dp" android:layout_marginEnd = "10dp" android:hint = "Course Description" android:importantForAutofill = "no" android:inputType = "text" /> <!--Button for updating your course to Firebase--> < Button android:id = "@+id/idBtnUpdateCourse" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_margin = "10dp" android:text = "Update Course Details" android:textAllCaps = "false" /> </ LinearLayout > |
Step 2: Updating our Modal Class where we were storing our data
In previous articles, we have seen creating our Modal class. In this article, we will update our Modal class so that we can pass our object class from adapter to our activity for navigation. Along with the implementation of serializable, we have to create a new string variable and create a getter and setter for that variable. We will be using that variable for storing the id of our document. Below is the code for the updated Courses.java class. Comments are added inside the code to get to know in more detail.
Java
import com.google.firebase.firestore.Exclude; import java.io.Serializable; // we have to implement our modal class // with serializable so that we can pass // our object class to new activity on // our item click of recycler view. public class Courses implements Serializable { // getter method for our id public String getId() { return id; } // setter method for our id public void setId(String id) { this .id = id; } // we are using exclude because // we are not saving our id @Exclude private String id; // variables for storing our data. private String courseName, courseDescription, courseDuration; public Courses() { // empty constructor required for Firebase. } // Constructor for all variables. public Courses(String courseName, String courseDescription, String courseDuration) { this .courseName = courseName; this .courseDescription = courseDescription; this .courseDuration = courseDuration; } // getter methods for all variables. public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this .courseName = courseName; } public String getCourseDescription() { return courseDescription; } // setter method for all variables. public void setCourseDescription(String courseDescription) { this .courseDescription = courseDescription; } public String getCourseDuration() { return courseDuration; } public void setCourseDuration(String courseDuration) { this .courseDuration = courseDuration; } } |
Step 3: Adding onClickListener() for our items of RecyclerView
As we have created our Adapter class in the previous article for displaying the list of courses in Recycler View. In this article, we will add onClickListener() inside that Adapter class for RecyclerView item click listener. Add the following code snippet to the CourseRVAdapter.java file.
Java
// here we are adding on click listener // for our item of recycler view. itemView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // after clicking of the item of recycler view. // we are passing our course object to the new activity. Courses courses = coursesArrayList.get(getAdapterPosition()); // below line is creating a new intent. Intent i = new Intent(context, UpdateCourse. class ); // below line is for putting our course object to our next activity. i.putExtra( "course" , courses); // after passing the data we are starting our activity. context.startActivity(i); } }); |
Below is the updated code for the CourseRVAdapter.java file.
Java
import android.content.Context; import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; public class CourseRVAdapter extends RecyclerView.Adapter<CourseRVAdapter.ViewHolder> { // creating variables for our ArrayList and context private ArrayList<Courses> coursesArrayList; private Context context; // creating constructor for our adapter class public CourseRVAdapter(ArrayList<Courses> coursesArrayList, Context context) { this .coursesArrayList = coursesArrayList; this .context = context; } @NonNull @Override public CourseRVAdapter.ViewHolder onCreateViewHolder( @NonNull ViewGroup parent, int viewType) { // passing our layout file for displaying our card item return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.course_item, parent, false )); } @Override public void onBindViewHolder( @NonNull CourseRVAdapter.ViewHolder holder, int position) { // setting data to our text views from our modal class. Courses courses = coursesArrayList.get(position); holder.courseNameTV.setText(courses.getCourseName()); holder.courseDurationTV.setText(courses.getCourseDuration()); holder.courseDescTV.setText(courses.getCourseDescription()); } @Override public int getItemCount() { // returning the size of our array list. return coursesArrayList.size(); } class ViewHolder extends RecyclerView.ViewHolder { // creating variables for our text views. private final TextView courseNameTV; private final TextView courseDurationTV; private final TextView courseDescTV; public ViewHolder( @NonNull View itemView) { super (itemView); // initializing our text views. courseNameTV = itemView.findViewById(R.id.idTVCourseName); courseDurationTV = itemView.findViewById(R.id.idTVCourseDuration); courseDescTV = itemView.findViewById(R.id.idTVCourseDescription); // here we are adding on click listener // for our item of recycler view. itemView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // after clicking of the item of recycler view. // we are passing our course object to the new activity. Courses courses = coursesArrayList.get(getAdapterPosition()); // below line is creating a new intent. Intent i = new Intent(context, UpdateCourse. class ); // below line is for putting our course object to our next activity. i.putExtra( "course" , courses); // after passing the data we are starting our activity. context.startActivity(i); } }); } } } |
Step 4: Update code in the CourseDetails.java file
As we have created a new variable inside our modal class for storing document id so we have to initialize that variable and pass our document id inside that variable. For passing that document id we have to update our code for the CourseDetails.java file where we are displaying the list of all the courses which we have added. Add the following code snippet to the CourseRVAdapter.java file.
Java
// below is the updated line of code which we have to // add to pass the document id inside our modal class. // we are setting our document id with d.getId() method c.setId(d.getId()); |
Below is the updated code for the CourseDetails.java file.
Java
import android.os.Bundle; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.firestore.DocumentSnapshot; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.QuerySnapshot; import java.util.ArrayList; import java.util.List; public class CourseDetails extends AppCompatActivity { // creating variables for our recycler view, // array list, adapter, firebase firestore // and our progress bar. private RecyclerView courseRV; private ArrayList<Courses> coursesArrayList; private CourseRVAdapter courseRVAdapter; private FirebaseFirestore db; ProgressBar loadingPB; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_course_details); // initializing our variables. courseRV = findViewById(R.id.idRVCourses); loadingPB = findViewById(R.id.idProgressBar); // initializing our variable for firebase // firestore and getting its instance. db = FirebaseFirestore.getInstance(); // creating our new array list coursesArrayList = new ArrayList<>(); courseRV.setHasFixedSize( true ); courseRV.setLayoutManager( new LinearLayoutManager( this )); // adding our array list to our recycler view adapter class. courseRVAdapter = new CourseRVAdapter(coursesArrayList, this ); // setting adapter to our recycler view. courseRV.setAdapter(courseRVAdapter); // below line is use to get the data from Firebase Firestore. // previously we were saving data on a reference of Courses // now we will be getting the data from the same reference. db.collection( "Courses" ).get() .addOnSuccessListener( new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { // after getting the data we are calling on success method // and inside this method we are checking if the received // query snapshot is empty or not. if (!queryDocumentSnapshots.isEmpty()) { // if the snapshot is not empty we are // hiding our progress bar and adding // our data in a list. loadingPB.setVisibility(View.GONE); List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments(); for (DocumentSnapshot d : list) { // after getting this list we are passing // that list to our object class. Courses c = d.toObject(Courses. class ); // below is the updated line of code which we have to // add to pass the document id inside our modal class. // we are setting our document id with d.getId() method c.setId(d.getId()); // and we will pass this object class // inside our arraylist which we have // created for recycler view. coursesArrayList.add(c); } // after adding the data to recycler view. // we are calling recycler view notifyDataSetChanged // method to notify that data has been changed in recycler view. courseRVAdapter.notifyDataSetChanged(); } else { // if the snapshot is empty we are displaying a toast message. Toast.makeText(CourseDetails. this , "No data found in Database" , Toast.LENGTH_SHORT).show(); } } }).addOnFailureListener( new OnFailureListener() { @Override public void onFailure( @NonNull Exception e) { // if we do not get any data or any error we are displaying // a toast message that we do not get any data Toast.makeText(CourseDetails. this , "Fail to get the data." , Toast.LENGTH_SHORT).show(); } }); } } |
Step 5: Now we will move towards the implementation of our UpdateCourses.java file
After updating our Adapter class, navigate to the app > java > your app’s package name > UpdateCourses.java file and add the below code to it. Comments are added inside the code to understand the code in more detail.
Java
import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.firestore.FirebaseFirestore; public class UpdateCourse extends AppCompatActivity { // creating variables for our edit text private EditText courseNameEdt, courseDurationEdt, courseDescriptionEdt; // creating a strings for storing our values from Edittext fields. private String courseName, courseDuration, courseDescription; // creating a variable for firebasefirestore. private FirebaseFirestore db; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_update_course); Courses courses = (Courses) getIntent().getSerializableExtra( "course" ); // getting our instance from Firebase Firestore. db = FirebaseFirestore.getInstance(); // initializing our edittext and buttons courseNameEdt = findViewById(R.id.idEdtCourseName); courseDescriptionEdt = findViewById(R.id.idEdtCourseDescription); courseDurationEdt = findViewById(R.id.idEdtCourseDuration); // creating variable for button Button updateCOurseBtn = findViewById(R.id.idBtnUpdateCourse); courseNameEdt.setText(courses.getCourseName()); courseDescriptionEdt.setText(courses.getCourseDescription()); courseDurationEdt.setText(courses.getCourseDuration()); updateCOurseBtn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { courseName = courseNameEdt.getText().toString(); courseDescription = courseDescriptionEdt.getText().toString(); courseDuration = courseDurationEdt.getText().toString(); // validating the text fields if empty or not. if (TextUtils.isEmpty(courseName)) { courseNameEdt.setError( "Please enter Course Name" ); } else if (TextUtils.isEmpty(courseDescription)) { courseDescriptionEdt.setError( "Please enter Course Description" ); } else if (TextUtils.isEmpty(courseDuration)) { courseDurationEdt.setError( "Please enter Course Duration" ); } else { // calling a method to update our course. // we are passing our object class, course name, // course description and course duration from our edittext field. updateCourses(courses, courseName, courseDescription, courseDuration); } } }); } private void updateCourses(Courses courses, String courseName, String courseDescription, String courseDuration) { // inside this method we are passing our updated values // inside our object class and later on we // will pass our whole object to firebase Firestore. Courses updatedCourse = new Courses(courseName, courseDescription, courseDuration); // after passing data to object class we are // sending it to firebase with specific document id. // below line is use to get the collection of our Firebase Firestore. db.collection( "Courses" ). // below line is use toset the id of // document where we have to perform // update operation. document(courses.getId()). // after setting our document id we are // passing our whole object class to it. set(updatedCourse). // after passing our object class we are // calling a method for on success listener. addOnSuccessListener( new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // on successful completion of this process // we are displaying the toast message. Toast.makeText(UpdateCourse. this , "Course has been updated.." , Toast.LENGTH_SHORT).show(); } }).addOnFailureListener( new OnFailureListener() { // inside on failure method we are // displaying a failure message. @Override public void onFailure( @NonNull Exception e) { Toast.makeText(UpdateCourse. this , "Fail to update the data.." , Toast.LENGTH_SHORT).show(); } }); } } |