在 Android 中使用 Firebase 实时数据库进行用户身份验证和 CRUD 操作
Firebase 是谷歌的著名产品,许多开发人员使用它为他们的网站和应用程序添加后端功能。 Firebase 将使您的后端数据库和处理数据库的工作变得更加轻松。在本文中,我们将看看 Firebase 实时数据库在 Android 中的实现。在本文中,我们将在我们的应用程序中添加电子邮件和密码身份验证,同时我们将使用 Firebase 实时数据库在我们的应用程序中执行CRUD(创建、读取、更新和删除)操作。
我们将在本文中构建什么?
在本文中,我们将构建一个简单的 Android 应用程序,我们将首先使用他们的电子邮件和密码对用户进行身份验证。之后,我们将在回收站视图中显示 Geeks for Geeks 上可用的课程列表。我们将能够对这些课程执行 CRUD 操作。在下面的视频中,我们将看到我们将在本文中构建的内容。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Java作为编程语言。
第 2 步:将您的应用连接到 Firebase
创建新项目后,导航到顶部栏上的“工具”选项。在里面点击 Firebase。单击 Firebase 后,您可以在屏幕截图中看到下面提到的右列。
在该列中导航到 Firebase 实时数据库。单击该选项,您将看到“将应用程序连接到 Firebase”和“将 Firebase 实时数据库添加到您的应用程序”这两个选项。单击立即连接,您的应用将连接到 Firebase。之后单击第二个选项,现在您的应用程序已连接到 Firebase。
将您的应用连接到 Firebase 后,您将看到以下屏幕。
之后验证 Firebase 实时数据库的依赖项是否已添加到我们的 Gradle 文件中。现在导航到app > Gradle Scripts并在该文件中检查是否添加了以下依赖项。如果您的 build.gradle 文件中未添加以下依赖项。在依赖项部分添加以下依赖项。下面是完整的依赖项部分,其中有身份验证和数据库的依赖项。
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
// dependency for picasso for loading image from url
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// dependency for firebase database.
implementation 'com.google.firebase:firebase-database:20.0.0'
implementation platform('com.google.firebase:firebase-bom:28.2.1')
// dependency for firebase authentication.
implementation 'com.google.firebase:firebase-auth'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
添加此依赖项后,同步您的项目,现在我们已准备好创建我们的应用程序。如果您想详细了解如何将您的应用连接到 Firebase。请参阅本文以详细了解将 Firebase 添加到 Android 应用程序。
第 3 步:创建 4 个不同的空活动
导航到应用程序 > 您的应用程序包名称 > 右键单击它 > 新建 > 活动 > 选择空活动并创建新活动。下面是我们在创建新活动时必须传递的四个不同活动的名称。
- AddCourseActivity :我们将使用此活动添加新课程。
- EditCourseActivity :此活动将用于编辑我们的课程以及删除我们的课程。
- LoginActivity :此活动将用于现有用户登录的登录目的。
- RegisterActivity :此活动用于注册新用户。
主要活动。 Java文件将已经存在,我们将在其中显示 RecyclerView 中的课程列表。
第 4 步:使用 AndroidManifest.xml 文件
导航到app > AndroidManifest.xml文件并为其添加 Internet 权限。下面是 AndroidManifest.xml 文件的完整代码。在此文件中,我们还将启动器活动更改为登录活动。代码中添加了注释,以便更详细地了解。
XML
XML
#296D98
#296D98
#296D98
#FF03DAC5
#FF018786
#FF000000
#FFFFFFFF
#0e2433
#1C4966
#22252D
#296D98
#296D98
#424242
#ffa500
#0D2162
#17388E
#12B2E6
XML
XML
XML
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
public class RegisterActivity extends AppCompatActivity {
// cretaing variables for edit text and textview,
// firebase auth, button and progress bar.
private TextInputEditText userNameEdt, passwordEdt, confirmPwdEdt;
private TextView loginTV;
private Button registerBtn;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
// initializing all our variables.
userNameEdt = findViewById(R.id.idEdtUserName);
passwordEdt = findViewById(R.id.idEdtPassword);
loadingPB = findViewById(R.id.idPBLoading);
confirmPwdEdt = findViewById(R.id.idEdtConfirmPassword);
loginTV = findViewById(R.id.idTVLoginUser);
registerBtn = findViewById(R.id.idBtnRegister);
mAuth = FirebaseAuth.getInstance();
// adding on click for login tv.
loginTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// opening a login activity on clicking login text.
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
}
});
// adding click listener for register button.
registerBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// hiding our progress bar.
loadingPB.setVisibility(View.VISIBLE);
// getting data fro =m our edit text.
String userName = userNameEdt.getText().toString();
String pwd = passwordEdt.getText().toString();
String cnfPwd = confirmPwdEdt.getText().toString();
// checking if the password and confirm password is equal or not.
if (!pwd.equals(cnfPwd)) {
Toast.makeText(RegisterActivity.this, "Please check both having same password..", Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(userName) && TextUtils.isEmpty(pwd) && TextUtils.isEmpty(cnfPwd)) {
// checking if the text fields are empty or not.
Toast.makeText(RegisterActivity.this, "Please enter your credentials..", Toast.LENGTH_SHORT).show();
} else {
// on below line we are creating a new user by passing email and password.
mAuth.createUserWithEmailAndPassword(userName, pwd).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// on below line we are checking if the task is success or not.
if (task.isSuccessful()) {
// in on success method we are hiding our progress bar and opening a login activity.
loadingPB.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "User Registered..", Toast.LENGTH_SHORT).show();
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
finish();
} else {
// in else condition we are displaying a failure toast message.
loadingPB.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "Fail to register user..", Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
}
}
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class LoginActivity extends AppCompatActivity {
// creating variable for edit text, textview,
// button, progress bar and firebase auth.
private TextInputEditText userNameEdt, passwordEdt;
private Button loginBtn;
private TextView newUserTV;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// initializing all our variables.
userNameEdt = findViewById(R.id.idEdtUserName);
passwordEdt = findViewById(R.id.idEdtPassword);
loginBtn = findViewById(R.id.idBtnLogin);
newUserTV = findViewById(R.id.idTVNewUser);
mAuth = FirebaseAuth.getInstance();
loadingPB = findViewById(R.id.idPBLoading);
// adding click listener for our new user tv.
newUserTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line opening a login activity.
Intent i = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(i);
}
});
// adding on click listener for our login button.
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// hiding our progress bar.
loadingPB.setVisibility(View.VISIBLE);
// getting data from our edit text on below line.
String email = userNameEdt.getText().toString();
String password = passwordEdt.getText().toString();
// on below line validating the text input.
if (TextUtils.isEmpty(email) && TextUtils.isEmpty(password)) {
Toast.makeText(LoginActivity.this, "Please enter your credentials..", Toast.LENGTH_SHORT).show();
return;
}
// on below line we are calling a sign in method and passing email and password to it.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// on below line we are checking if the task is succes or not.
if (task.isSuccessful()) {
// on below line we are hiding our progress bar.
loadingPB.setVisibility(View.GONE);
Toast.makeText(LoginActivity.this, "Login Successful..", Toast.LENGTH_SHORT).show();
// on below line we are opening our mainactivity.
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
finish();
} else {
// hiding our progress bar and displaying a toast message.
loadingPB.setVisibility(View.GONE);
Toast.makeText(LoginActivity.this, "Please enter valid user credentials..", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
@Override
protected void onStart() {
super.onStart();
// in on start method checking if
// the user is already sign in.
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
// if the user is not null then we are
// opening a main activity on below line.
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
this.finish();
}
}
}
Java
package com.gtappdevelopers.firebasecrudapp;
import android.os.Parcel;
import android.os.Parcelable;
public class CourseRVModal implements Parcelable {
// creating variables for our different fields.
private String courseName;
private String courseDescription;
private String coursePrice;
private String bestSuitedFor;
private String courseImg;
private String courseLink;
private String courseId;
public String getCourseId() {
return courseId;
}
public void setCourseId(String courseId) {
this.courseId = courseId;
}
// creating an empty constructor.
public CourseRVModal() {
}
protected CourseRVModal(Parcel in) {
courseName = in.readString();
courseId = in.readString();
courseDescription = in.readString();
coursePrice = in.readString();
bestSuitedFor = in.readString();
courseImg = in.readString();
courseLink = in.readString();
}
public static final Creator CREATOR = new Creator() {
@Override
public CourseRVModal createFromParcel(Parcel in) {
return new CourseRVModal(in);
}
@Override
public CourseRVModal[] newArray(int size) {
return new CourseRVModal[size];
}
};
// creating getter and setter methods.
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getCourseDescription() {
return courseDescription;
}
public void setCourseDescription(String courseDescription) {
this.courseDescription = courseDescription;
}
public String getCoursePrice() {
return coursePrice;
}
public void setCoursePrice(String coursePrice) {
this.coursePrice = coursePrice;
}
public String getBestSuitedFor() {
return bestSuitedFor;
}
public void setBestSuitedFor(String bestSuitedFor) {
this.bestSuitedFor = bestSuitedFor;
}
public String getCourseImg() {
return courseImg;
}
public void setCourseImg(String courseImg) {
this.courseImg = courseImg;
}
public String getCourseLink() {
return courseLink;
}
public void setCourseLink(String courseLink) {
this.courseLink = courseLink;
}
public CourseRVModal(String courseId, String courseName, String courseDescription, String coursePrice, String bestSuitedFor, String courseImg, String courseLink) {
this.courseName = courseName;
this.courseId = courseId;
this.courseDescription = courseDescription;
this.coursePrice = coursePrice;
this.bestSuitedFor = bestSuitedFor;
this.courseImg = courseImg;
this.courseLink = courseLink;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(courseName);
dest.writeString(courseId);
dest.writeString(courseDescription);
dest.writeString(coursePrice);
dest.writeString(bestSuitedFor);
dest.writeString(courseImg);
dest.writeString(courseLink);
}
}
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class AddCourseActivity extends AppCompatActivity {
// creating variables for our button, edit text,
// firebase database, database refrence, progress bar.
private Button addCourseBtn;
private TextInputEditText courseNameEdt, courseDescEdt, coursePriceEdt, bestSuitedEdt, courseImgEdt, courseLinkEdt;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
private ProgressBar loadingPB;
private String courseID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course);
// initializing all our variables.
addCourseBtn = findViewById(R.id.idBtnAddCourse);
courseNameEdt = findViewById(R.id.idEdtCourseName);
courseDescEdt = findViewById(R.id.idEdtCourseDescription);
coursePriceEdt = findViewById(R.id.idEdtCoursePrice);
bestSuitedEdt = findViewById(R.id.idEdtSuitedFor);
courseImgEdt = findViewById(R.id.idEdtCourseImageLink);
courseLinkEdt = findViewById(R.id.idEdtCourseLink);
loadingPB = findViewById(R.id.idPBLoading);
firebaseDatabase = FirebaseDatabase.getInstance();
// on below line creating our database reference.
databaseReference = firebaseDatabase.getReference("Courses");
// adding click listener for our add course button.
addCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadingPB.setVisibility(View.VISIBLE);
// getting data from our edit text.
String courseName = courseNameEdt.getText().toString();
String courseDesc = courseDescEdt.getText().toString();
String coursePrice = coursePriceEdt.getText().toString();
String bestSuited = bestSuitedEdt.getText().toString();
String courseImg = courseImgEdt.getText().toString();
String courseLink = courseLinkEdt.getText().toString();
courseID = courseName;
// on below line we are passing all data to our modal class.
CourseRVModal courseRVModal = new CourseRVModal(courseID, courseName, courseDesc, coursePrice, bestSuited, courseImg, courseLink);
// on below line we are calling a add value event
// to pass data to firebase database.
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
// on below line we are setting data in our firebase database.
databaseReference.child(courseID).setValue(courseRVModal);
// displaying a toast message.
Toast.makeText(AddCourseActivity.this, "Course Added..", Toast.LENGTH_SHORT).show();
// starting a main activity.
startActivity(new Intent(AddCourseActivity.this, MainActivity.class));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
// displaying a failure message on below line.
Toast.makeText(AddCourseActivity.this, "Fail to add Course..", Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
XML
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class CourseRVAdapter extends RecyclerView.Adapter {
// creating variables for our list, context, interface and position.
private ArrayList courseRVModalArrayList;
private Context context;
private CourseClickInterface courseClickInterface;
int lastPos = -1;
// creating a constructor.
public CourseRVAdapter(ArrayList courseRVModalArrayList, Context context, CourseClickInterface courseClickInterface) {
this.courseRVModalArrayList = courseRVModalArrayList;
this.context = context;
this.courseClickInterface = courseClickInterface;
}
@NonNull
@Override
public CourseRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(context).inflate(R.layout.course_rv_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CourseRVAdapter.ViewHolder holder, int position) {
// setting data to our recycler view item on below line.
CourseRVModal courseRVModal = courseRVModalArrayList.get(position);
holder.courseTV.setText(courseRVModal.getCourseName());
holder.coursePriceTV.setText("Rs. " + courseRVModal.getCoursePrice());
Picasso.get().load(courseRVModal.getCourseImg()).into(holder.courseIV);
// adding animation to recycler view item on below line.
setAnimation(holder.itemView, position);
holder.courseIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
courseClickInterface.onCourseClick(position);
}
});
}
private void setAnimation(View itemView, int position) {
if (position > lastPos) {
// on below line we are setting animation.
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
itemView.setAnimation(animation);
lastPos = position;
}
}
@Override
public int getItemCount() {
return courseRVModalArrayList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
// creating variable for our image view and text view on below line.
private ImageView courseIV;
private TextView courseTV, coursePriceTV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all our variables on below line.
courseIV = itemView.findViewById(R.id.idIVCourse);
courseTV = itemView.findViewById(R.id.idTVCOurseName);
coursePriceTV = itemView.findViewById(R.id.idTVCousePrice);
}
}
// creating a interface for on click
public interface CourseClickInterface {
void onCourseClick(int position);
}
}
XML
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements CourseRVAdapter.CourseClickInterface {
// creating variables for fab, firebase database,
// progress bar, list, adapter,firebase auth,
// recycler view and relative layout.
private FloatingActionButton addCourseFAB;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
private RecyclerView courseRV;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
private ArrayList courseRVModalArrayList;
private CourseRVAdapter courseRVAdapter;
private RelativeLayout homeRL;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing all our variables.
courseRV = findViewById(R.id.idRVCourses);
homeRL = findViewById(R.id.idRLBSheet);
loadingPB = findViewById(R.id.idPBLoading);
addCourseFAB = findViewById(R.id.idFABAddCourse);
firebaseDatabase = FirebaseDatabase.getInstance();
mAuth = FirebaseAuth.getInstance();
courseRVModalArrayList = new ArrayList<>();
// on below line we are getting database reference.
databaseReference = firebaseDatabase.getReference("Courses");
// on below line adding a click listener for our floating action button.
addCourseFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// opening a new activity for adding a course.
Intent i = new Intent(MainActivity.this, AddCourseActivity.class);
startActivity(i);
}
});
// on below line initializing our adapter class.
courseRVAdapter = new CourseRVAdapter(courseRVModalArrayList, this, this::onCourseClick);
// setting layout malinger to recycler view on below line.
courseRV.setLayoutManager(new LinearLayoutManager(this));
// setting adapter to recycler view on below line.
courseRV.setAdapter(courseRVAdapter);
// on below line calling a method to fetch courses from database.
getCourses();
}
private void getCourses() {
// on below line clearing our list.
courseRVModalArrayList.clear();
// on below line we are calling add child event listener method to read the data.
databaseReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// on below line we are hiding our progress bar.
loadingPB.setVisibility(View.GONE);
// adding snapshot to our array list on below line.
courseRVModalArrayList.add(snapshot.getValue(CourseRVModal.class));
// notifying our adapter that data has changed.
courseRVAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// this method is called when new child is added
// we are notifying our adapter and making progress bar
// visibility as gone.
loadingPB.setVisibility(View.GONE);
courseRVAdapter.notifyDataSetChanged();
}
@Override
public void onChildRemoved(@NonNull DataSnapshot snapshot) {
// notifying our adapter when child is removed.
courseRVAdapter.notifyDataSetChanged();
loadingPB.setVisibility(View.GONE);
}
@Override
public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// notifying our adapter when child is moved.
courseRVAdapter.notifyDataSetChanged();
loadingPB.setVisibility(View.GONE);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public void onCourseClick(int position) {
// calling a method to display a bottom sheet on below line.
displayBottomSheet(courseRVModalArrayList.get(position));
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// adding a click listener for option selected on below line.
int id = item.getItemId();
switch (id) {
case R.id.idLogOut:
// displaying a toast message on user logged out inside on click.
Toast.makeText(getApplicationContext(), "User Logged Out", Toast.LENGTH_LONG).show();
// on below line we are signing out our user.
mAuth.signOut();
// on below line we are opening our login activity.
Intent i = new Intent(MainActivity.this, LoginActivity.class);
startActivity(i);
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// on below line we are inflating our menu
// file for displaying our menu options.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void displayBottomSheet(CourseRVModal modal) {
// on below line we are creating our bottom sheet dialog.
final BottomSheetDialog bottomSheetTeachersDialog = new BottomSheetDialog(this, R.style.BottomSheetDialogTheme);
// on below line we are inflating our layout file for our bottom sheet.
View layout = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_layout, homeRL);
// setting content view for bottom sheet on below line.
bottomSheetTeachersDialog.setContentView(layout);
// on below line we are setting a cancelable
bottomSheetTeachersDialog.setCancelable(false);
bottomSheetTeachersDialog.setCanceledOnTouchOutside(true);
// calling a method to display our bottom sheet.
bottomSheetTeachersDialog.show();
// on below line we are creating variables for
// our text view and image view inside bottom sheet
// and initialing them with their ids.
TextView courseNameTV = layout.findViewById(R.id.idTVCourseName);
TextView courseDescTV = layout.findViewById(R.id.idTVCourseDesc);
TextView suitedForTV = layout.findViewById(R.id.idTVSuitedFor);
TextView priceTV = layout.findViewById(R.id.idTVCoursePrice);
ImageView courseIV = layout.findViewById(R.id.idIVCourse);
// on below line we are setting data to different views on below line.
courseNameTV.setText(modal.getCourseName());
courseDescTV.setText(modal.getCourseDescription());
suitedForTV.setText("Suited for " + modal.getBestSuitedFor());
priceTV.setText("Rs." + modal.getCoursePrice());
Picasso.get().load(modal.getCourseImg()).into(courseIV);
Button viewBtn = layout.findViewById(R.id.idBtnVIewDetails);
Button editBtn = layout.findViewById(R.id.idBtnEditCourse);
// adding on click listener for our edit button.
editBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are opening our EditCourseActivity on below line.
Intent i = new Intent(MainActivity.this, EditCourseActivity.class);
// on below line we are passing our course modal
i.putExtra("course", modal);
startActivity(i);
}
});
// adding click listener for our view button on below line.
viewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are navigating to browser
// for displaying course details from its url
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(modal.getCourseLink()));
startActivity(i);
}
});
}
}
XML
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Map;
public class EditCourseActivity extends AppCompatActivity {
// creating variables for our edit text, firebase database,
// database reference, course rv modal,progress bar.
private TextInputEditText courseNameEdt, courseDescEdt, coursePriceEdt, bestSuitedEdt, courseImgEdt, courseLinkEdt;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
CourseRVModal courseRVModal;
private ProgressBar loadingPB;
// creating a string for our course id.
private String courseID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_course);
// initializing all our variables on below line.
Button addCourseBtn = findViewById(R.id.idBtnAddCourse);
courseNameEdt = findViewById(R.id.idEdtCourseName);
courseDescEdt = findViewById(R.id.idEdtCourseDescription);
coursePriceEdt = findViewById(R.id.idEdtCoursePrice);
bestSuitedEdt = findViewById(R.id.idEdtSuitedFor);
courseImgEdt = findViewById(R.id.idEdtCourseImageLink);
courseLinkEdt = findViewById(R.id.idEdtCourseLink);
loadingPB = findViewById(R.id.idPBLoading);
firebaseDatabase = FirebaseDatabase.getInstance();
// on below line we are getting our modal class on which we have passed.
courseRVModal = getIntent().getParcelableExtra("course");
Button deleteCourseBtn = findViewById(R.id.idBtnDeleteCourse);
if (courseRVModal != null) {
// on below line we are setting data to our edit text from our modal class.
courseNameEdt.setText(courseRVModal.getCourseName());
coursePriceEdt.setText(courseRVModal.getCoursePrice());
bestSuitedEdt.setText(courseRVModal.getBestSuitedFor());
courseImgEdt.setText(courseRVModal.getCourseImg());
courseLinkEdt.setText(courseRVModal.getCourseLink());
courseDescEdt.setText(courseRVModal.getCourseDescription());
courseID = courseRVModal.getCourseId();
}
// on below line we are initialing our database reference and we are adding a child as our course id.
databaseReference = firebaseDatabase.getReference("Courses").child(courseID);
// on below line we are adding click listener for our add course button.
addCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are making our progress bar as visible.
loadingPB.setVisibility(View.VISIBLE);
// on below line we are getting data from our edit text.
String courseName = courseNameEdt.getText().toString();
String courseDesc = courseDescEdt.getText().toString();
String coursePrice = coursePriceEdt.getText().toString();
String bestSuited = bestSuitedEdt.getText().toString();
String courseImg = courseImgEdt.getText().toString();
String courseLink = courseLinkEdt.getText().toString();
// on below line we are creating a map for
// passing a data using key and value pair.
Map map = new HashMap<>();
map.put("courseName", courseName);
map.put("courseDescription", courseDesc);
map.put("coursePrice", coursePrice);
map.put("bestSuitedFor", bestSuited);
map.put("courseImg", courseImg);
map.put("courseLink", courseLink);
map.put("courseId", courseID);
// on below line we are calling a database reference on
// add value event listener and on data change method
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
// making progress bar visibility as gone.
loadingPB.setVisibility(View.GONE);
// adding a map to our database.
databaseReference.updateChildren(map);
// on below line we are displaying a toast message.
Toast.makeText(EditCourseActivity.this, "Course Updated..", Toast.LENGTH_SHORT).show();
// opening a new activity after updating our coarse.
startActivity(new Intent(EditCourseActivity.this, MainActivity.class));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
// displaying a failure message on toast.
Toast.makeText(EditCourseActivity.this, "Fail to update course..", Toast.LENGTH_SHORT).show();
}
});
}
});
// adding a click listener for our delete course button.
deleteCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// calling a method to delete a course.
deleteCourse();
}
});
}
private void deleteCourse() {
// on below line calling a method to delete the course.
databaseReference.removeValue();
// displaying a toast message on below line.
Toast.makeText(this, "Course Deleted..", Toast.LENGTH_SHORT).show();
// opening a main activity on below line.
startActivity(new Intent(EditCourseActivity.this, MainActivity.class));
}
}
步骤 5:更新 colors.xml 文件
导航到app > res > values > colors.xml并将以下颜色添加到其中。
XML
#296D98
#296D98
#296D98
#FF03DAC5
#FF018786
#FF000000
#FFFFFFFF
#0e2433
#1C4966
#22252D
#296D98
#296D98
#424242
#ffa500
#0D2162
#17388E
#12B2E6
第 6 步:更新我们的 themes.xml 文件
导航到app > res > values > themes.xml并将以下代码添加到其中。
XML
第 7 步:为我们的按钮和自定义进度条背景创建自定义背景
导航到应用程序 > res > drawable > 右键单击它 > New Drawable Resource 文件并将其命名为button_back并向其添加以下代码。代码中添加注释,详细了解。
XML
导航到应用程序 > res > drawable > 右键单击它 > New Drawable Resource 文件并将其命名为progress_back并将以下代码添加到其中。代码中添加注释,详细了解。
XML
步骤 8:使用 activity_register.xml 文件
导航到app > res > activity_register.xml并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
XML
第 9 步:使用 RegisterActivity。 Java文件
导航到应用程序 > Java > 您应用程序的包名称 > RegisterActivity。 Java文件并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
public class RegisterActivity extends AppCompatActivity {
// cretaing variables for edit text and textview,
// firebase auth, button and progress bar.
private TextInputEditText userNameEdt, passwordEdt, confirmPwdEdt;
private TextView loginTV;
private Button registerBtn;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
// initializing all our variables.
userNameEdt = findViewById(R.id.idEdtUserName);
passwordEdt = findViewById(R.id.idEdtPassword);
loadingPB = findViewById(R.id.idPBLoading);
confirmPwdEdt = findViewById(R.id.idEdtConfirmPassword);
loginTV = findViewById(R.id.idTVLoginUser);
registerBtn = findViewById(R.id.idBtnRegister);
mAuth = FirebaseAuth.getInstance();
// adding on click for login tv.
loginTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// opening a login activity on clicking login text.
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
}
});
// adding click listener for register button.
registerBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// hiding our progress bar.
loadingPB.setVisibility(View.VISIBLE);
// getting data fro =m our edit text.
String userName = userNameEdt.getText().toString();
String pwd = passwordEdt.getText().toString();
String cnfPwd = confirmPwdEdt.getText().toString();
// checking if the password and confirm password is equal or not.
if (!pwd.equals(cnfPwd)) {
Toast.makeText(RegisterActivity.this, "Please check both having same password..", Toast.LENGTH_SHORT).show();
} else if (TextUtils.isEmpty(userName) && TextUtils.isEmpty(pwd) && TextUtils.isEmpty(cnfPwd)) {
// checking if the text fields are empty or not.
Toast.makeText(RegisterActivity.this, "Please enter your credentials..", Toast.LENGTH_SHORT).show();
} else {
// on below line we are creating a new user by passing email and password.
mAuth.createUserWithEmailAndPassword(userName, pwd).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// on below line we are checking if the task is success or not.
if (task.isSuccessful()) {
// in on success method we are hiding our progress bar and opening a login activity.
loadingPB.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "User Registered..", Toast.LENGTH_SHORT).show();
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
finish();
} else {
// in else condition we are displaying a failure toast message.
loadingPB.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "Fail to register user..", Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
}
}
步骤 10:使用 activity_login.xml 文件
导航到app > res > activity_login.xml并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
XML
第 11 步:使用 LoginActivity。 Java文件
导航到应用程序 > Java > 您应用程序的包名称 > LoginActivity。 Java文件并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class LoginActivity extends AppCompatActivity {
// creating variable for edit text, textview,
// button, progress bar and firebase auth.
private TextInputEditText userNameEdt, passwordEdt;
private Button loginBtn;
private TextView newUserTV;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// initializing all our variables.
userNameEdt = findViewById(R.id.idEdtUserName);
passwordEdt = findViewById(R.id.idEdtPassword);
loginBtn = findViewById(R.id.idBtnLogin);
newUserTV = findViewById(R.id.idTVNewUser);
mAuth = FirebaseAuth.getInstance();
loadingPB = findViewById(R.id.idPBLoading);
// adding click listener for our new user tv.
newUserTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line opening a login activity.
Intent i = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(i);
}
});
// adding on click listener for our login button.
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// hiding our progress bar.
loadingPB.setVisibility(View.VISIBLE);
// getting data from our edit text on below line.
String email = userNameEdt.getText().toString();
String password = passwordEdt.getText().toString();
// on below line validating the text input.
if (TextUtils.isEmpty(email) && TextUtils.isEmpty(password)) {
Toast.makeText(LoginActivity.this, "Please enter your credentials..", Toast.LENGTH_SHORT).show();
return;
}
// on below line we are calling a sign in method and passing email and password to it.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// on below line we are checking if the task is succes or not.
if (task.isSuccessful()) {
// on below line we are hiding our progress bar.
loadingPB.setVisibility(View.GONE);
Toast.makeText(LoginActivity.this, "Login Successful..", Toast.LENGTH_SHORT).show();
// on below line we are opening our mainactivity.
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
finish();
} else {
// hiding our progress bar and displaying a toast message.
loadingPB.setVisibility(View.GONE);
Toast.makeText(LoginActivity.this, "Please enter valid user credentials..", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
@Override
protected void onStart() {
super.onStart();
// in on start method checking if
// the user is already sign in.
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
// if the user is not null then we are
// opening a main activity on below line.
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
this.finish();
}
}
}
第 12 步:为要在 RecyclerView 中显示的数据创建一个 Modal 类
导航到应用程序 > Java > 您应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为CourseRVModal并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.os.Parcel;
import android.os.Parcelable;
public class CourseRVModal implements Parcelable {
// creating variables for our different fields.
private String courseName;
private String courseDescription;
private String coursePrice;
private String bestSuitedFor;
private String courseImg;
private String courseLink;
private String courseId;
public String getCourseId() {
return courseId;
}
public void setCourseId(String courseId) {
this.courseId = courseId;
}
// creating an empty constructor.
public CourseRVModal() {
}
protected CourseRVModal(Parcel in) {
courseName = in.readString();
courseId = in.readString();
courseDescription = in.readString();
coursePrice = in.readString();
bestSuitedFor = in.readString();
courseImg = in.readString();
courseLink = in.readString();
}
public static final Creator CREATOR = new Creator() {
@Override
public CourseRVModal createFromParcel(Parcel in) {
return new CourseRVModal(in);
}
@Override
public CourseRVModal[] newArray(int size) {
return new CourseRVModal[size];
}
};
// creating getter and setter methods.
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public String getCourseDescription() {
return courseDescription;
}
public void setCourseDescription(String courseDescription) {
this.courseDescription = courseDescription;
}
public String getCoursePrice() {
return coursePrice;
}
public void setCoursePrice(String coursePrice) {
this.coursePrice = coursePrice;
}
public String getBestSuitedFor() {
return bestSuitedFor;
}
public void setBestSuitedFor(String bestSuitedFor) {
this.bestSuitedFor = bestSuitedFor;
}
public String getCourseImg() {
return courseImg;
}
public void setCourseImg(String courseImg) {
this.courseImg = courseImg;
}
public String getCourseLink() {
return courseLink;
}
public void setCourseLink(String courseLink) {
this.courseLink = courseLink;
}
public CourseRVModal(String courseId, String courseName, String courseDescription, String coursePrice, String bestSuitedFor, String courseImg, String courseLink) {
this.courseName = courseName;
this.courseId = courseId;
this.courseDescription = courseDescription;
this.coursePrice = coursePrice;
this.bestSuitedFor = bestSuitedFor;
this.courseImg = courseImg;
this.courseLink = courseLink;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(courseName);
dest.writeString(courseId);
dest.writeString(courseDescription);
dest.writeString(coursePrice);
dest.writeString(bestSuitedFor);
dest.writeString(courseImg);
dest.writeString(courseLink);
}
}
数据库中的 CREATE 操作
第 13 步:使用 activity_add_course.xml 文件
导航到app > res > layout > activity_add_course.xml并将以下代码添加到其中。代码中添加了注释以了解更多细节。
XML
第 14 步:使用 AddCourseActivity。 Java文件
导航到应用程序 > Java > 您应用程序的包名称 > AddCourseActivity。 Java文件并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class AddCourseActivity extends AppCompatActivity {
// creating variables for our button, edit text,
// firebase database, database refrence, progress bar.
private Button addCourseBtn;
private TextInputEditText courseNameEdt, courseDescEdt, coursePriceEdt, bestSuitedEdt, courseImgEdt, courseLinkEdt;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
private ProgressBar loadingPB;
private String courseID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_course);
// initializing all our variables.
addCourseBtn = findViewById(R.id.idBtnAddCourse);
courseNameEdt = findViewById(R.id.idEdtCourseName);
courseDescEdt = findViewById(R.id.idEdtCourseDescription);
coursePriceEdt = findViewById(R.id.idEdtCoursePrice);
bestSuitedEdt = findViewById(R.id.idEdtSuitedFor);
courseImgEdt = findViewById(R.id.idEdtCourseImageLink);
courseLinkEdt = findViewById(R.id.idEdtCourseLink);
loadingPB = findViewById(R.id.idPBLoading);
firebaseDatabase = FirebaseDatabase.getInstance();
// on below line creating our database reference.
databaseReference = firebaseDatabase.getReference("Courses");
// adding click listener for our add course button.
addCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadingPB.setVisibility(View.VISIBLE);
// getting data from our edit text.
String courseName = courseNameEdt.getText().toString();
String courseDesc = courseDescEdt.getText().toString();
String coursePrice = coursePriceEdt.getText().toString();
String bestSuited = bestSuitedEdt.getText().toString();
String courseImg = courseImgEdt.getText().toString();
String courseLink = courseLinkEdt.getText().toString();
courseID = courseName;
// on below line we are passing all data to our modal class.
CourseRVModal courseRVModal = new CourseRVModal(courseID, courseName, courseDesc, coursePrice, bestSuited, courseImg, courseLink);
// on below line we are calling a add value event
// to pass data to firebase database.
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
// on below line we are setting data in our firebase database.
databaseReference.child(courseID).setValue(courseRVModal);
// displaying a toast message.
Toast.makeText(AddCourseActivity.this, "Course Added..", Toast.LENGTH_SHORT).show();
// starting a main activity.
startActivity(new Intent(AddCourseActivity.this, MainActivity.class));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
// displaying a failure message on below line.
Toast.makeText(AddCourseActivity.this, "Fail to add Course..", Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
从数据库读取操作
第 15 步:在我们的 Recycler 视图中为每门课程创建一个项目。
导航到app > res > 右键单击它 > 新建布局资源文件并将其命名为course_rv_item并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
XML
第 16 步:使用 activity_main.xml 文件
导航到app > res > layout > activity_main.xml并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
XML
第十七步:创建一个Adapter类,用于为RecyclerView的每一项设置数据
导航到应用程序 > Java > 您应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为CourseRVAdapter并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class CourseRVAdapter extends RecyclerView.Adapter {
// creating variables for our list, context, interface and position.
private ArrayList courseRVModalArrayList;
private Context context;
private CourseClickInterface courseClickInterface;
int lastPos = -1;
// creating a constructor.
public CourseRVAdapter(ArrayList courseRVModalArrayList, Context context, CourseClickInterface courseClickInterface) {
this.courseRVModalArrayList = courseRVModalArrayList;
this.context = context;
this.courseClickInterface = courseClickInterface;
}
@NonNull
@Override
public CourseRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(context).inflate(R.layout.course_rv_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CourseRVAdapter.ViewHolder holder, int position) {
// setting data to our recycler view item on below line.
CourseRVModal courseRVModal = courseRVModalArrayList.get(position);
holder.courseTV.setText(courseRVModal.getCourseName());
holder.coursePriceTV.setText("Rs. " + courseRVModal.getCoursePrice());
Picasso.get().load(courseRVModal.getCourseImg()).into(holder.courseIV);
// adding animation to recycler view item on below line.
setAnimation(holder.itemView, position);
holder.courseIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
courseClickInterface.onCourseClick(position);
}
});
}
private void setAnimation(View itemView, int position) {
if (position > lastPos) {
// on below line we are setting animation.
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
itemView.setAnimation(animation);
lastPos = position;
}
}
@Override
public int getItemCount() {
return courseRVModalArrayList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
// creating variable for our image view and text view on below line.
private ImageView courseIV;
private TextView courseTV, coursePriceTV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all our variables on below line.
courseIV = itemView.findViewById(R.id.idIVCourse);
courseTV = itemView.findViewById(R.id.idTVCOurseName);
coursePriceTV = itemView.findViewById(R.id.idTVCousePrice);
}
}
// creating a interface for on click
public interface CourseClickInterface {
void onCourseClick(int position);
}
}
步骤 18:创建用于显示菜单选项的菜单文件
导航到应用程序 > res > 右键单击它 > 新建 > 目录并将其命名为菜单。现在导航到菜单目录,右键单击它 > 新建 > 菜单资源文件并将其命名为menu_main.xml并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
XML
步骤 19:创建用于显示底部工作表的布局文件
导航到应用程序 > res > 布局 > 右键单击它 > 新建 > 布局资源文件并将其命名为bottom_sheet_layout并向其添加以下代码。代码中添加了注释,以便更详细地了解。
XML
第 20 步:使用 MainActivity。 Java文件
导航到应用程序 > Java > 您应用程序的包名称 > MainActivity。 Java文件并将以下代码添加到其中。代码中添加注释,详细了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements CourseRVAdapter.CourseClickInterface {
// creating variables for fab, firebase database,
// progress bar, list, adapter,firebase auth,
// recycler view and relative layout.
private FloatingActionButton addCourseFAB;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
private RecyclerView courseRV;
private FirebaseAuth mAuth;
private ProgressBar loadingPB;
private ArrayList courseRVModalArrayList;
private CourseRVAdapter courseRVAdapter;
private RelativeLayout homeRL;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing all our variables.
courseRV = findViewById(R.id.idRVCourses);
homeRL = findViewById(R.id.idRLBSheet);
loadingPB = findViewById(R.id.idPBLoading);
addCourseFAB = findViewById(R.id.idFABAddCourse);
firebaseDatabase = FirebaseDatabase.getInstance();
mAuth = FirebaseAuth.getInstance();
courseRVModalArrayList = new ArrayList<>();
// on below line we are getting database reference.
databaseReference = firebaseDatabase.getReference("Courses");
// on below line adding a click listener for our floating action button.
addCourseFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// opening a new activity for adding a course.
Intent i = new Intent(MainActivity.this, AddCourseActivity.class);
startActivity(i);
}
});
// on below line initializing our adapter class.
courseRVAdapter = new CourseRVAdapter(courseRVModalArrayList, this, this::onCourseClick);
// setting layout malinger to recycler view on below line.
courseRV.setLayoutManager(new LinearLayoutManager(this));
// setting adapter to recycler view on below line.
courseRV.setAdapter(courseRVAdapter);
// on below line calling a method to fetch courses from database.
getCourses();
}
private void getCourses() {
// on below line clearing our list.
courseRVModalArrayList.clear();
// on below line we are calling add child event listener method to read the data.
databaseReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// on below line we are hiding our progress bar.
loadingPB.setVisibility(View.GONE);
// adding snapshot to our array list on below line.
courseRVModalArrayList.add(snapshot.getValue(CourseRVModal.class));
// notifying our adapter that data has changed.
courseRVAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// this method is called when new child is added
// we are notifying our adapter and making progress bar
// visibility as gone.
loadingPB.setVisibility(View.GONE);
courseRVAdapter.notifyDataSetChanged();
}
@Override
public void onChildRemoved(@NonNull DataSnapshot snapshot) {
// notifying our adapter when child is removed.
courseRVAdapter.notifyDataSetChanged();
loadingPB.setVisibility(View.GONE);
}
@Override
public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
// notifying our adapter when child is moved.
courseRVAdapter.notifyDataSetChanged();
loadingPB.setVisibility(View.GONE);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public void onCourseClick(int position) {
// calling a method to display a bottom sheet on below line.
displayBottomSheet(courseRVModalArrayList.get(position));
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// adding a click listener for option selected on below line.
int id = item.getItemId();
switch (id) {
case R.id.idLogOut:
// displaying a toast message on user logged out inside on click.
Toast.makeText(getApplicationContext(), "User Logged Out", Toast.LENGTH_LONG).show();
// on below line we are signing out our user.
mAuth.signOut();
// on below line we are opening our login activity.
Intent i = new Intent(MainActivity.this, LoginActivity.class);
startActivity(i);
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// on below line we are inflating our menu
// file for displaying our menu options.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void displayBottomSheet(CourseRVModal modal) {
// on below line we are creating our bottom sheet dialog.
final BottomSheetDialog bottomSheetTeachersDialog = new BottomSheetDialog(this, R.style.BottomSheetDialogTheme);
// on below line we are inflating our layout file for our bottom sheet.
View layout = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_layout, homeRL);
// setting content view for bottom sheet on below line.
bottomSheetTeachersDialog.setContentView(layout);
// on below line we are setting a cancelable
bottomSheetTeachersDialog.setCancelable(false);
bottomSheetTeachersDialog.setCanceledOnTouchOutside(true);
// calling a method to display our bottom sheet.
bottomSheetTeachersDialog.show();
// on below line we are creating variables for
// our text view and image view inside bottom sheet
// and initialing them with their ids.
TextView courseNameTV = layout.findViewById(R.id.idTVCourseName);
TextView courseDescTV = layout.findViewById(R.id.idTVCourseDesc);
TextView suitedForTV = layout.findViewById(R.id.idTVSuitedFor);
TextView priceTV = layout.findViewById(R.id.idTVCoursePrice);
ImageView courseIV = layout.findViewById(R.id.idIVCourse);
// on below line we are setting data to different views on below line.
courseNameTV.setText(modal.getCourseName());
courseDescTV.setText(modal.getCourseDescription());
suitedForTV.setText("Suited for " + modal.getBestSuitedFor());
priceTV.setText("Rs." + modal.getCoursePrice());
Picasso.get().load(modal.getCourseImg()).into(courseIV);
Button viewBtn = layout.findViewById(R.id.idBtnVIewDetails);
Button editBtn = layout.findViewById(R.id.idBtnEditCourse);
// adding on click listener for our edit button.
editBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are opening our EditCourseActivity on below line.
Intent i = new Intent(MainActivity.this, EditCourseActivity.class);
// on below line we are passing our course modal
i.putExtra("course", modal);
startActivity(i);
}
});
// adding click listener for our view button on below line.
viewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are navigating to browser
// for displaying course details from its url
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(modal.getCourseLink()));
startActivity(i);
}
});
}
}
数据库中的编辑和删除操作
步骤 21:使用 activity_edit_course.xml 文件
导航到app > res > layout > activity_edit_course.xml并将以下代码添加到其中。代码中添加注释,详细了解。
XML
第 22 步:使用 EditCourseActivity。 Java文件
导航到应用程序 > Java > 您应用程序的包名称 > EditCourseActivity。 Java文件并将以下代码添加到其中。代码中添加了注释,以便更详细地了解。
Java
package com.gtappdevelopers.firebasecrudapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Map;
public class EditCourseActivity extends AppCompatActivity {
// creating variables for our edit text, firebase database,
// database reference, course rv modal,progress bar.
private TextInputEditText courseNameEdt, courseDescEdt, coursePriceEdt, bestSuitedEdt, courseImgEdt, courseLinkEdt;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
CourseRVModal courseRVModal;
private ProgressBar loadingPB;
// creating a string for our course id.
private String courseID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_course);
// initializing all our variables on below line.
Button addCourseBtn = findViewById(R.id.idBtnAddCourse);
courseNameEdt = findViewById(R.id.idEdtCourseName);
courseDescEdt = findViewById(R.id.idEdtCourseDescription);
coursePriceEdt = findViewById(R.id.idEdtCoursePrice);
bestSuitedEdt = findViewById(R.id.idEdtSuitedFor);
courseImgEdt = findViewById(R.id.idEdtCourseImageLink);
courseLinkEdt = findViewById(R.id.idEdtCourseLink);
loadingPB = findViewById(R.id.idPBLoading);
firebaseDatabase = FirebaseDatabase.getInstance();
// on below line we are getting our modal class on which we have passed.
courseRVModal = getIntent().getParcelableExtra("course");
Button deleteCourseBtn = findViewById(R.id.idBtnDeleteCourse);
if (courseRVModal != null) {
// on below line we are setting data to our edit text from our modal class.
courseNameEdt.setText(courseRVModal.getCourseName());
coursePriceEdt.setText(courseRVModal.getCoursePrice());
bestSuitedEdt.setText(courseRVModal.getBestSuitedFor());
courseImgEdt.setText(courseRVModal.getCourseImg());
courseLinkEdt.setText(courseRVModal.getCourseLink());
courseDescEdt.setText(courseRVModal.getCourseDescription());
courseID = courseRVModal.getCourseId();
}
// on below line we are initialing our database reference and we are adding a child as our course id.
databaseReference = firebaseDatabase.getReference("Courses").child(courseID);
// on below line we are adding click listener for our add course button.
addCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// on below line we are making our progress bar as visible.
loadingPB.setVisibility(View.VISIBLE);
// on below line we are getting data from our edit text.
String courseName = courseNameEdt.getText().toString();
String courseDesc = courseDescEdt.getText().toString();
String coursePrice = coursePriceEdt.getText().toString();
String bestSuited = bestSuitedEdt.getText().toString();
String courseImg = courseImgEdt.getText().toString();
String courseLink = courseLinkEdt.getText().toString();
// on below line we are creating a map for
// passing a data using key and value pair.
Map map = new HashMap<>();
map.put("courseName", courseName);
map.put("courseDescription", courseDesc);
map.put("coursePrice", coursePrice);
map.put("bestSuitedFor", bestSuited);
map.put("courseImg", courseImg);
map.put("courseLink", courseLink);
map.put("courseId", courseID);
// on below line we are calling a database reference on
// add value event listener and on data change method
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
// making progress bar visibility as gone.
loadingPB.setVisibility(View.GONE);
// adding a map to our database.
databaseReference.updateChildren(map);
// on below line we are displaying a toast message.
Toast.makeText(EditCourseActivity.this, "Course Updated..", Toast.LENGTH_SHORT).show();
// opening a new activity after updating our coarse.
startActivity(new Intent(EditCourseActivity.this, MainActivity.class));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
// displaying a failure message on toast.
Toast.makeText(EditCourseActivity.this, "Fail to update course..", Toast.LENGTH_SHORT).show();
}
});
}
});
// adding a click listener for our delete course button.
deleteCourseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// calling a method to delete a course.
deleteCourse();
}
});
}
private void deleteCourse() {
// on below line calling a method to delete the course.
databaseReference.removeValue();
// displaying a toast message on below line.
Toast.makeText(this, "Course Deleted..", Toast.LENGTH_SHORT).show();
// opening a main activity on below line.
startActivity(new Intent(EditCourseActivity.this, MainActivity.class));
}
}
Note: All the drawable used inside the application are present in the app > res > drawable. You can check out the project on the below GitHub link.
现在运行您的应用程序并查看应用程序的输出。
输出: