I've created a favourites page using a RecyclerView with data saved on firebase. I'm attempting to delete an item from both firebase and the recyclerview in realtime. I can remove the item using
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(position);
However, I can't remove the last item, but it deletes in firebase. I've tried different combinations of
notifyDataSetChanged();
notifyItemRemoved(position);
notifyItemRangeChanged(position, countries.size());
But with no luck so far, I can't see where I'm going wrong.
Populating recyclerview
Public class FavouritesFragment extends Fragment {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
RecyclerView.Adapter adapter;
ArrayList<Country> countries;
private FirebaseAuth firebaseAuth;
private DatabaseReference databaseReference;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_favourites, container, false);
getActivity().setTitle("Favourites");
firebaseAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference();
FirebaseUser user = firebaseAuth.getCurrentUser();
String userID = user.getUid();
databaseReference = databaseReference.child("users").child(userID).child("Favourites");
recyclerView = view.findViewById(R.id.favourites_recycler);
countries = new ArrayList<>();
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
addFavourites();
return view;
}
public void addFavourites(){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
Country c = ds.getValue(Country.class);
countries.add(c);
}
adapter = new FavouritesAdapter(countries);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Deleting from RecyclerView in adapter class
public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.MyViewHolder>{
ArrayList<Country> countries;
private View view;
ImageBindingAdapter imageBindingAdapter = new ImageBindingAdapter();
RecyclerView recyclerView;
private int position;
private FirebaseDatabase firebaseDatabase;
private FirebaseAuth firebaseAuth;
private DatabaseReference databaseReference;
public FavouritesAdapter(ArrayList<Country> countries1){
countries = countries1;
}
#NonNull
#Override
public FavouritesAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.favourites, viewGroup, false);
recyclerView = view.findViewById(R.id.favourites_recycler);
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference();
FirebaseUser user = firebaseAuth.getCurrentUser();
String userID = user.getUid();
databaseReference = databaseReference.child("users").child(userID).child("Favourites");
return new FavouritesAdapter.MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int i) {
myViewHolder.name.setText(countries.get(i).getName());
myViewHolder.snippet.setText(countries.get(i).getSnippet());
myViewHolder.popUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(view.getContext(), view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_to_favs:
deleteFavourite();
break;
default:
return false;
}
return true;
}
});
}
});
#Override
public int getItemCount() {
return countries.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public ImageView popUp;
public MyViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.cityName);
popUp = itemView.findViewById(R.id.dotsPopUp);
}
}
public void deleteFavourite(){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String id = countries.get(position).getId();
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(position);
// notifyDataSetChanged();
// notifyItemRemoved(position);
// notifyItemRangeChanged(position, countries.size());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}); }
}
In your adapter you didn't set the position to the position of the item you need to delete. So when the user hits the delete item in the popUp menu, you call deleteFavourite();, but you need to set the class field position before calling deleteFavourite().
So, in onBindViewHolder, you need to assign the value of the second parameter to the position, and it's better to pass it to deleteFavourite() method as a paraemter like deleteFavourite(position):
#Override
public void onBindViewHolder(#NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int pos) {
....
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_to_favs:
deleteFavourite(pos);
break;
default:
return false;
}
return true;
}
});
Then change your deleteFavourite to accept the new parameter, and notifyItemRemoved(position);
public void deleteFavourite(int pos){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String id = countries.get(pos).getId();
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(pos).getId()).getRef().removeValue();
countries.remove(pos);
notifyItemRemoved(pos);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Do this to remove object from list, in deleteFavourite() function:
..........
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(countries.get(position));
notifyDataSetChanged();
}
..............
Related
I am making an application in which products are inserted into the database and I am inserting the 1 product once. it is working fine. But when I delete a specific node/ product from Database. deletion code is also working fine but at the same time product is again adding into the database.
Main Fragment Code;
public class Products_fragment extends Fragment {
FloatingActionButton fab_addproduct;
RecyclerView recyclerView;
EditText searchview;
BottomSheetDialog bottomSheetDialog;
FirebaseDatabase firebaseDatabase;
ArrayList<Product_model> DatabaseProductlist;
FirebaseAuth auth;
CircularDotsLoader ProgressBar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_products_fragment, container, false);
setviews(view);
setInitilization();
setclicks();
setadapter();
return view;
}
private void setInitilization() {
DatabaseProductlist = new ArrayList<>();
}
private void setadapter() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
assert currentFirebaseUser != null;
String UID = currentFirebaseUser.getUid();
DatabaseReference reference = database.getReference("Users").child(UID).child("Products");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
ProgressBar.setVisibility(View.GONE);
DatabaseProductlist.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Product_model model = dataSnapshot.getValue(Product_model.class);
DatabaseProductlist.add(model);
}
Product_Adapter product_adapter = new Product_Adapter(DatabaseProductlist);
recyclerView.setAdapter(product_adapter);
product_adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
ToastUtility.showErrorToast(getContext(), error.getMessage());
}
});
}
private void setclicks() {
fab_addproduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bottomSheetDialog = new BottomSheetDialog(getContext(), R.style.AppBottomSheetDialogTheme);
bottomSheetDialog.setContentView(R.layout.productadd_bottom_sheet);
TextInputEditText product_id = bottomSheetDialog.findViewById(R.id.product_id);
TextInputEditText product_name = bottomSheetDialog.findViewById(R.id.product_name);
TextInputEditText product_quantity = bottomSheetDialog.findViewById(R.id.product_quantity);
MaterialButton add_btn = bottomSheetDialog.findViewById(R.id.add_btn);
TextInputEditText product_price = bottomSheetDialog.findViewById(R.id.product_price);
add_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Objects.requireNonNull(product_name.getText()).toString().isEmpty() || product_id.getText().toString().isEmpty() || product_price.getText().toString().isEmpty() || product_quantity.getText().toString().isEmpty()) {
ToastUtility.showErrorToast(getContext(), "Please Fill all Fields");
} else {
Product_model model = new Product_model(Integer.parseInt(product_id.getText().toString()), Integer.parseInt(product_quantity.getText().toString()), Integer.parseInt(product_price.getText().toString()), product_name.getText().toString());
firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference reference = firebaseDatabase.getReference("Users");
FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
assert currentFirebaseUser != null;
String UID = currentFirebaseUser.getUid();
reference.child(UID).child("Products").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.child(product_name.getText().toString().trim()).exists()) {
ToastUtility.showErrorToast(getContext(),"Product Already Exists!");
}
else{
reference.child(UID).child("Products").child(product_name.getText().toString().trim()).setValue(model).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
ToastUtility.showSuccessToast(getContext(),"Successfully Added");
setadapter();
}
else{
ToastUtility.showErrorToast(getContext(), Objects.requireNonNull(task.getException()).getMessage());
}
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
ToastUtility.showErrorToast(getContext(),error.getMessage());
}
});
}
}
});
bottomSheetDialog.show();
}
});
}
private void setviews(View view) {
recyclerView = view.findViewById(R.id.recyclerView);
fab_addproduct = view.findViewById(R.id.fab_addproduct);
searchview = view.findViewById(R.id.searchview);
ProgressBar = view.findViewById(R.id.progressbar);
}
}
Adapter Code:
public class Product_Adapter extends RecyclerView.Adapter<Product_Adapter.myviewholder> {
ArrayList<Product_model> dataholder;
public Product_Adapter(ArrayList<Product_model> dataholder) {
this.dataholder = dataholder;
}
#NonNull
#Override
public myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.singlerow_product, parent, false);
return new myviewholder(view); }
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull myviewholder holder, int position) {
holder.idtv.setText("" + dataholder.get(position).getId());
holder.pnametv.setText("" + dataholder.get(position).getProduct_name());
holder.pqtytv.setText("" + dataholder.get(position).getProduct_quantity());
holder.ppritv.setText("" + dataholder.get(position).getProduct_price());
holder.delimg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseDatabase db = FirebaseDatabase.getInstance();
FirebaseUser curUser = FirebaseAuth.getInstance().getCurrentUser();
assert curUser != null;
String UID = curUser.getUid();
String productname = dataholder.get(holder.getAdapterPosition()).getProduct_name();
DatabaseReference reference = db.getReference("Users").child(UID).child("Products");
reference.child(productname).setValue(null).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
ToastUtility.showSuccessToast(view.getContext(),"Suucessfully Deleted");
notifyItemRemoved(holder.getAdapterPosition());
}
else
{
ToastUtility.showErrorToast(view.getContext(),"Product is not deleting ");
}
}
});
}
});
}
#Override
public int getItemCount() {
return dataholder.size();
}
static class myviewholder extends RecyclerView.ViewHolder{
TextView idtv, pnametv, pqtytv, ppritv, delimg, edit_img;
public myviewholder(#NonNull View itemView) {
super(itemView);
idtv = itemView.findViewById(R.id.idtv);
pnametv = itemView.findViewById(R.id.pnametv);
pqtytv = itemView.findViewById(R.id.pqtytv);
ppritv = itemView.findViewById(R.id.ppritv);
delimg = itemView.findViewById(R.id.delimg);
edit_img = itemView.findViewById(R.id.edit_img);
}
}
}
When you click delete, shouldn't you remove your item from the list before notifying data changed:
//this code belongs to the part where you click the delete
.........
reference.child(productname).setValue(null).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
ToastUtility.showSuccessToast(view.getContext(),"Suucessfully Deleted");
//here remove the item from your list
dataholder.remove(holder.getAdapterPosition());
//then notify the adapter
notifyItemRemoved(holder.getAdapterPosition());
}
I had user shared preferences to get the current Uid or other Uid from realtime database. But I need to do the same without the use of shared preferences. This is for my ProfileActivity and I am using viewpager with three different fragments. The shared preferences show only the current user's profile even when searched for other user in the app.
The image attached is the output of the profile activity in my smartphone. The top bar containing the username and the logout button is of the profile activity and the rest below the blue banner is of the viewpager
public class ProfileActivity extends AppCompatActivity {
private ImageView logout;
private TextView post;
private FloatingActionButton floatingActionButton;
private TabLayout tabLayout;
private ViewPager viewPager;
private TextView username;
private FirebaseUser fUser;
private DatabaseReference databaseReference;
private FirebaseDatabase firebaseDatabase;
private FirebaseAuth firebaseAuth;
String profileId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
fUser = FirebaseAuth.getInstance().getCurrentUser();
firebaseAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference()
.child("Users").child(Objects.requireNonNull(firebaseAuth.getUid()));
String data = getBaseContext().getSharedPreferences("PROFILE", Context.MODE_PRIVATE)
.getString("profileId", "none");
if (data.equals("none")){
profileId = fUser.getUid();
} else{
profileId = data;
}
logout = findViewById(R.id.log_out);
username = findViewById(R.id.username);
floatingActionButton = findViewById(R.id.floatingActionButton);
post = findViewById(R.id.posts_account);
tabLayout = findViewById(R.id.tab_layout);
viewPager = findViewById(R.id.view_pager);
tabLayout.setupWithViewPager(viewPager);
VPAdapter vpAdapter = new VPAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
vpAdapter.addFragment(new Profile(), "Profile");
vpAdapter.addFragment(new MyPosts(), "Posts");
if (profileId.equals(fUser.getUid())){
vpAdapter.addFragment(new SavedPosts(), "Saved");
}
viewPager.setAdapter(vpAdapter);
getPostCount();
userInfo();
getSupportActionBar().hide();
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(ProfileActivity.this, PostActivity.class));
finish();
}
});
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog alertDialog = new AlertDialog.Builder(ProfileActivity.this).create();
alertDialog.setTitle("Are you sure to logout?");
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(ProfileActivity.this, StartActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
}
});
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE)
.setTextColor(ContextCompat.getColor(ProfileActivity.this, R.color.colorRed));
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(ProfileActivity.this, R.color.colorRed));
}
});
}
private void getPostCount() {
FirebaseDatabase.getInstance().getReference().child("Posts").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
int counter = 0;
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Posts posts = snapshot.getValue(Posts.class);
if (posts.getPublisher().equals(profileId)) counter ++;
}
post.setText(String.valueOf(counter));
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void userInfo() {
FirebaseDatabase.getInstance().getReference().child("Users").child(profileId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
User user = snapshot.getValue(User.class);
username.setText("#" + user.getUsername());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
The above is the code of the profile activity
public class MyPosts extends Fragment {
private RecyclerView recyclerView;
private PostAdapter photoAdapter;
private List<Posts> myPhotoList;
private FirebaseUser fUser;
String profileId;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_my_thoughts, container, false);
fUser = FirebaseAuth.getInstance().getCurrentUser();
String data = getContext().getSharedPreferences("PROFILE", Context.MODE_PRIVATE)
.getString("profileId", "none");
if (data.equals("none")){
profileId = fUser.getUid();
} else{
profileId = data;
}
recyclerView = view.findViewById(R.id.recycler_view_pictures);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 1));
myPhotoList = new ArrayList<>();
photoAdapter = new PostAdapter(getContext(), myPhotoList);
recyclerView.setAdapter(photoAdapter);
myPhotos();
return view;
}
private void myPhotos() {
FirebaseDatabase.getInstance().getReference().child("Posts").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
myPhotoList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Posts post = snapshot.getValue(Posts.class);
if (post.getPublisher().equals(profileId)){
myPhotoList.add(post);
}
}
Collections.reverse(myPhotoList);
photoAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
the above is the code for the posts fragments inside the viewpager of the profile activity
public class Profile extends Fragment {
private CircleImageView imageProfile;
private TextView followers;
private TextView following;
private TextView fullname;
private TextView bio;
private CircleImageView verification;
private TextView usernamebottom;
private Button editProfile;
private FirebaseUser fUser;
String profileId;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_profile, container, false);
fUser = FirebaseAuth.getInstance().getCurrentUser();
String data = getContext().getSharedPreferences("PROFILE", Context.MODE_PRIVATE)
.getString("profileId", "none");
if (data.equals("none")){
profileId = fUser.getUid();
} else{
profileId = data;
getContext().getSharedPreferences("PROFILE", Context.MODE_PRIVATE).edit().clear().apply();
}
imageProfile = view.findViewById(R.id.image_profile);
verification = view.findViewById(R.id.verification_profile);
followers = view.findViewById(R.id.followers);
following = view.findViewById(R.id.following);
fullname = view.findViewById(R.id.full_name);
bio = view.findViewById(R.id.bio);
usernamebottom = view.findViewById(R.id.username_btm);
editProfile = view.findViewById(R.id.edit_profile);
getFollowersAndFollowingCount();
userInfo();
if (profileId.equals(fUser.getUid())){
editProfile.setText("Edit profile");
} else {
checkFollowingStatus();
}
editProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String btnText = editProfile.getText().toString();
if (btnText.equals("Edit profile")){
//Go to edit profile
startActivity(new Intent(getContext(), EditProfileActivity.class));
} else{
if (btnText.equals("follow")){
FirebaseDatabase.getInstance().getReference().child("Follow").child(fUser.getUid())
.child("following").child(profileId).setValue(true);
FirebaseDatabase.getInstance().getReference().child("Follow")
.child(profileId).child("followers").child(fUser.getUid()).setValue(true);
} else {
FirebaseDatabase.getInstance().getReference().child("Follow").child(fUser.getUid())
.child("following").child(profileId).removeValue();
FirebaseDatabase.getInstance().getReference().child("Follow")
.child(profileId).child("followers").child(fUser.getUid()).removeValue();
}
}
}
});
return view;
}
private void checkFollowingStatus() {
FirebaseDatabase.getInstance().getReference().child("Follow").child(fUser.getUid()).child("following")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.child(profileId).exists()) {
editProfile.setText("following");
} else {
editProfile.setText("follow");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void getFollowersAndFollowingCount() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Follow").child(profileId);
ref.child("followers").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
followers.setText("" + dataSnapshot.getChildrenCount());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
ref.child("following").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
following.setText("" + dataSnapshot.getChildrenCount());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void userInfo() {
FirebaseDatabase.getInstance().getReference().child("Users").child(profileId).addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
User user = snapshot.getValue(User.class);
if (user.getImageurl().equals("default")){
imageProfile.setImageResource(R.drawable.ic_empty_profile);
} else {
Picasso.get().load(user.getImageurl()).into(imageProfile);
}
usernamebottom.setText("#" + user.getUsername());
fullname.setText(user.getName());
bio.setText(user.getBio());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
The above is the code of the user detail fragment also in the view pager of my profile activity
It is like social media app,This fragment should display the chat list, But it isn't, Here is the codes:
DirectMessagesFragment:
public class DirectMessagesFragment extends Fragment{
FirebaseAuth firebaseAuth;
FirebaseUser currentUser;
AdapterChatlist adapterChatlist;
DatabaseReference ref;
RecyclerView recyclerViewChatter;
List<ModelChatter> chatterList ;
List<ModelChatlist> chatlistList ;
public DirectMessagesFragment(){}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.fragment_direct_messages, container, false);
firebaseAuth = FirebaseAuth.getInstance();
currentUser = FirebaseAuth.getInstance().getCurrentUser();
recyclerViewChatter = view.findViewById(R.id.chatter_recyclerview);
chatlistList = new ArrayList<>();
ref = FirebaseDatabase.getInstance().getReference("Chatlist").child(currentUser.getUid());
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
chatlistList.clear();
for (DataSnapshot ds:snapshot.getChildren()){
ModelChatlist chatlist = ds.getValue(ModelChatlist.class);
chatlistList.add(chatlist);}
loadChats();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});
return view;
}
private void loadChats() {
chatterList = new ArrayList<>();
ref = FirebaseDatabase.getInstance().getReference("Users");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
chatterList.clear();
for (DataSnapshot ds:snapshot.getChildren()){
ModelChatter chatter = ds.getValue(ModelChatter.class);
for(ModelChatlist chatlist: chatlistList){
if(chatter.getUid() != null && chatter.getUid().equals(chatlist.getId())){
chatterList.add(chatter);
break;
}}
adapterChatlist = new AdapterChatlist(getContext(), chatterList);
recyclerViewChatter.setAdapter(adapterChatlist);
}}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});
}}
In ChatActivity:
//create chat list in firebase
DatabaseReference ref1 =
FirebaseDatabase.getInstance().getReference("ChatList")
.child(uid).child(hisUid);
ref1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(!snapshot.exists()){
ref1.child("id").setValue(hisUid);
}}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});
DatabaseReference ref2 = FirebaseDatabase.getInstance().getReference("ChatList")
.child(hisUid).child(uid);
ref2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(!snapshot.exists()){
ref2.child("id").setValue(uid);
}}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});}
#Override
public void afterTextChanged(Editable s) {
}
};
/////////
}
ModelChatlist only contain id.
ModelChatter contain name, image, uid.
AdapterChatlist:
public class AdapterChatlist extends RecyclerView.Adapter<AdapterChatlist.MyHolder>{
Context context;
List<ModelChatter> chattersList;
public AdapterChatlist(Context context, List<ModelChatter> chattersList) {
this.context = context;
this.chattersList = chattersList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.row_dm, parent, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
String userImage = chattersList.get(position).getImage();
String userName = chattersList.get(position).getName();
String hisUid = chattersList.get(position).getUid();
holder.chatter_name.setText(userName);
try {
Picasso.with(context).load(userImage).placeholder(R.drawable.user).into(holder.chatter_img);
} catch (Exception e){
Picasso.with(context).load(R.drawable.user).into(holder.chatter_img);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ChatActivity.class);
intent.putExtra("hisUid", hisUid);
context.startActivity(intent);
}
});}
#Override
public int getItemCount() {
return chattersList.size();}
class MyHolder extends RecyclerView.ViewHolder{
ImageView chatter_img;
TextView chatter_name;
public MyHolder(#NonNull View itemView) {
super(itemView);
chatter_img = itemView.findViewById(R.id.chatter_img);
chatter_name = itemView.findViewById(R.id.chatter_name);
}}}}
fragment_direct_messages layout contain the recyclerview, row_dm contain the cardview
Any help will be appreciated..
Pass chat list into your method
for (DataSnapshot ds:snapshot.getChildren()){
ModelChatlist chatlist = ds.getValue(ModelChatlist.class);
chatlistList.add(chatlist);
}
loadChats(chatlistList);
private void loadChats(List<ModelChatlist> chatlist) {
//your code
}
Try adding filters (like logging the data received) to check where the actual problem persists. It's difficult to go through so much code.
Hi I am trying to remove A row from a recycle view and once it is removed from the recycle view it should also be removed from the firebase realtime database. I am able to remove it from the recycle view but when I go back into my activity it repopulates with all the rows as I am unsure on how to remove it from Firebase. Can anyone help?
public class FindAllContacts extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
ArrayList<Contacts> contacts = new ArrayList<>();
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser firebaseUser = mAuth.getCurrentUser();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_all);
getSupportActionBar().setTitle("View All Contacts");
getAllContacts();
}
public void getAllContatcs() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Contacts");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot userSnapshot : snapshot.getChildren()) {
Contact contact = userSnapshot.getValue(Contact.class);
assert contact != null;
contatcs.add(contact);
recyclerView = findViewById(R.id.findAllRV);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(FindAll.this));
adapter = new MainAdapter(contacts);
new ItemTouchHelper(itemTouch).attachToRecyclerView(recyclerView);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(FindAll.this, "Error Occurred: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
ItemTouchHelper.SimpleCallback itemTouch = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
contatcs.remove(viewHolder.getAdapterPosition());
adapter.notifyDataSetChanged();
}
};
}
I've created a match system in my Android program that also includes a chat section which has 2 fragments. The first fragment shows your chats, the second one shows your matches by using RecyclerView and UsersAdapter. However, in the second (match) fragment, people who you matched with are shown many times. For example, the same person is seen many times as you can see here.
My code is below.
UserFragment:
public class UsersFragment extends Fragment {
private RecyclerView recyclerView;
private UsersAdapter usersAdapter;
private List<User> mUsers;
FirebaseFirestore usersfragmentstore;
FirebaseAuth readauth;
DocumentReference readref;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
usersfragmentstore = FirebaseFirestore.getInstance();
readauth = FirebaseAuth.getInstance();
View view = inflater.inflate(R.layout.fragment_users, container, false);
readref = usersfragmentstore.collection("users").document(readauth.getCurrentUser().getUid());
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mUsers = new ArrayList<>();
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
readref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot shot = task.getResult();
List<String> matchedid2 = new ArrayList<>();
matchedid2 = (List<String>) shot.get("matchlist");
if (matchedid2.contains(snapshot.getKey())) {
User user = snapshot.getValue(User.class);
mUsers.add(user);
usersAdapter = new UsersAdapter(getContext(), mUsers, false);
recyclerView.setAdapter(usersAdapter);
}
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return view;
}
}
UserAdapter:
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {
private Context mContext;
private List<User> mUsers;
private boolean ischat;
String theLastMessage;
public UsersAdapter(Context mContext, List<User> mUsers, boolean ischat) {
this.mUsers = mUsers;
this.mContext = mContext;
this.ischat = ischat;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item_chat, parent, false);
return new UsersAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
User user = mUsers.get(position);
holder.username.setText(user.getName());
if (user.getImageURL().equals("default")) {
holder.profile_image.setImageResource(R.drawable.profilepicture);
} else {
Glide.with(mContext).load(user.getImageURL()).into(holder.profile_image);
}
if (ischat) {
lastMessage(user.getId(), holder.last_msg);
} else {
holder.last_msg.setVisibility(View.GONE);
}
if (ischat) {
if (user.getStatus().equals("online")) {
holder.img_on.setVisibility(View.VISIBLE);
holder.img_off.setVisibility(View.GONE);
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.VISIBLE);
}
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, MessageActivity.class);
intent.putExtra("userid", user.getId());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public ImageView profile_image;
private ImageView img_on;
private ImageView img_off;
private TextView last_msg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
username = itemView.findViewById(R.id.chatusername);
profile_image = itemView.findViewById(R.id.profile_image);
img_on = itemView.findViewById(R.id.img_on);
img_off = itemView.findViewById(R.id.img_off);
last_msg = itemView.findViewById(R.id.last_msg);
}
}
private void lastMessage(final String userid, final TextView last_msg) {
theLastMessage = "defalut";
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chat chat = snapshot.getValue(Chat.class);
if (firebaseUser != null && chat != null) {
if (chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) || chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid())) {
theLastMessage = chat.getMessage();
}
}
}
switch (theLastMessage) {
case "default":
last_msg.setText("No message");
break;
default:
last_msg.setText(theLastMessage);
break;
}
theLastMessage = "default";
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
What am I missing?
befor adding new data first clear list by mUsers.clear(); as below
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
readref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot shot = task.getResult();
List<String> matchedid2 = new ArrayList<>();
matchedid2 = (List<String>) shot.get("matchlist");
if (matchedid2.contains(snapshot.getKey())) {
mUsers.clear();
User user = snapshot.getValue(User.class);
mUsers.add(user);
usersAdapter = new UsersAdapter(getContext(), mUsers, false);
recyclerView.setAdapter(usersAdapter);
}
}
});
}