I'm trying to remove data from my recyclerview and let it be updated in the mobile ui as well. It is an android app. I am able to delete the data alright but I always have to leave that page and come back when I make the changes. I tried making some modifications to the onChildRemoved method but I started getting crashes upon making this change. What do I do? Below is my code.
MainActivity.java
DatabaseReference databaseReference;
List<DataSnapshot> listData;
RecyclerView recyclerView;
MyCart.MyAdapter adapter;
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
listData = new ArrayList<>();
adapter = new MyCart.MyAdapter(listData);
adapter.setHasStableIds(true);
GetDataFirebase();
private void GetDataFirebase() {
databaseReference = FirebaseDatabase.getInstance().getReference()
.child("Customers")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart");
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Items students = dataSnapshot.getValue(Items.class);
listData.add(dataSnapshot);
recyclerView.setAdapter(adapter);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
int index = listData.indexOf(dataSnapshot);
listData.remove(index);
adapter.notifyDataSetChanged();
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyCart.MyAdapter.ViewHolder> {
List<DataSnapshot> list;
public MyAdapter(List<DataSnapshot> List) {
this.list = List;
}
#Override
public void onBindViewHolder(MyCart.MyAdapter.ViewHolder holder, int position) {
final DataSnapshot studentSnapshot = list.get(position);
final Items students = studentSnapshot.getValue(Items.class);
final String list_user_id = studentSnapshot.getKey();
holder.item_name.setText(students.getItem_name());
holder.item_price.setText(students.getItem_price());
Picasso.with(holder.item_image.getContext()).load(students.getItem_image()).placeholder(R.drawable.no_image_two).into(holder.item_image);
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference prod_ref = FirebaseDatabase.getInstance().getReference().child("Customers").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart").child(list_user_id);
prod_ref.removeValue();
adapter.notifyDataSetChanged();
Toast.makeText(MyCart.this, "Item removed from cart", Toast.LENGTH_SHORT).show();
}
});
}
#NonNull
#Override
public MyCart.MyAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_item_layout, parent, false);
return new MyCart.MyAdapter.ViewHolder(view);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView item_name, item_price;
ImageView item_image;
ImageView delete;
public ViewHolder(View itemView) {
super(itemView);
item_name = itemView.findViewById(R.id.item_name);
item_price = itemView.findViewById(R.id.item_price);
item_image = itemView.findViewById(R.id.item_image);
delete = itemView.findViewById(R.id.delete_item);
}
}
#Override
public int getItemCount() {
return list.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
}
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference prod_ref = FirebaseDatabase.getInstance().getReference().child("Customers").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart").child(list_user_id);
prod_ref.removeValue();
//add/modify these two lines here
list.remove(position);
notifyDataSetChanged();
}
});
And one more change you need to do
// move this toast to onChildRemoved method and clear the other code from there
Toast.makeText(MyCart.this, "Item removed from cart", Toast.LENGTH_SHORT).show();
like
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
//remove these line these will raise the exception and Toast here
int index = listData.indexOf(dataSnapshot);
listData.remove(index);
adapter.notifyDataSetChanged();
}
When dataSnapshot does not exist in list, it returns -1. Index of list start from 0. Therefore, you're this getting error. You need to add a guard check here like:
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
int index = listData.indexOf(dataSnapshot);
if(index > 0) {
listData.remove(index);
}
adapter.notifyDataSetChanged();
}
Related
Java
Here is the code of fragment of my app and when I run it my app crashes as soon as I start the app got Customer home fragment it crashes, In logcat its showing there is error in CustomerHomefragemnt so here's the code as I am not being able to troubleshoot it Please answer if someone can help. Here is my fragment code`
public class CustomerHomeFragment extends Fragment implements
SwipeRefreshLayout.OnRefreshListener {
RecyclerView recyclerView;
private List<UpdateDishModel> updateDishModelList;
private CustomerHomeAdapter adapter;
String State, City, Sub;
DatabaseReference dataaa, databaseReference;
SwipeRefreshLayout swipeRefreshLayout;
SearchView searchView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_customerhome, null);
setHasOptionsMenu(true);
recyclerView = v.findViewById(R.id.recycle_menu);
recyclerView.setHasFixedSize(true);
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.move);
recyclerView.startAnimation(animation);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
updateDishModelList = new ArrayList<>();
swipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipelayout);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimaryDark, R.color.green);
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
dataaa = FirebaseDatabase.getInstance()
.getReference("Customer").child(userid);
dataaa.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Customer cust = dataSnapshot.getValue(Customer.class);
State = cust.getState();
City = cust.getCity();
Sub = cust.getSuburban();
customermenu();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
return v;
}
#Override
public void onRefresh() {
customermenu();
}
private void customermenu() {
swipeRefreshLayout.setRefreshing(true);
DatabaseReference databaseReference =
FirebaseDatabase.getInstance().getReference("FoodSupplyDetails")
.child(State).child(City).child(Sub);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
updateDishModelList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
UpdateDishModel updateDishModel =
snapshot1.getValue(UpdateDishModel.class);
updateDishModelList.add(updateDishModel);
}
}
adapter = new CustomerHomeAdapter(getContext(), updateDishModelList);
recyclerView.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
swipeRefreshLayout.setRefreshing(false);
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
private void search(final String searchtext) {
ArrayList<UpdateDishModel> mylist = new ArrayList<>();
for (UpdateDishModel object : updateDishModelList) {
if (object.getDishes().toLowerCase().contains(searchtext.toLowerCase())) {
mylist.add(object);
}
}
adapter = new CustomerHomeAdapter(getContext(), mylist);
recyclerView.setAdapter(adapter);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search, menu);
MenuItem menuItem = menu.findItem(R.id.Searchdish);
searchView = (SearchView) menuItem.getActionView();
searchView.setQueryHint("Search Dish");
}
}
```
`here is my Homeadapter code`
public class CustomerHomeAdapter extends
RecyclerView.Adapter<CustomerHomeAdapter.ViewHolder>
{
private Context mcontext;
private List<UpdateDishModel>updateDishModellist;
DatabaseReference databaseReference;
public CustomerHomeAdapter(Context context,List<UpdateDishModel>updateDishModellist)
{
this.updateDishModellist=updateDishModellist;
this.mcontext=context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view=
LayoutInflater.from(mcontext)
.inflate(R.layout.customer_menudish,parent,false);
return new CustomerHomeAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
final UpdateDishModel updateDishModel=updateDishModellist.get(position);
Glide.with(mcontext).load(updateDishModel.getImageURL()).into(holder.imageView);
holder.Dishname.setText(updateDishModel.getDishes());
updateDishModel.getRandomUID();
updateDishModel.getChefId();
holder.price.setText("Price: ₹ " + updateDishModel.getPrice());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(mcontext,OrderDish.class);
intent.putExtra("FoodMenu",updateDishModel.getRandomUID());
intent.putExtra("ChefId",updateDishModel.getChefId());
mcontext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return updateDishModellist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView Dishname,price;
ElegantNumberButton additem;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.menu_image);
Dishname=itemView.findViewById(R.id.dishname);
price=itemView.findViewById(R.id.dishprice);
additem=itemView.findViewById(R.id.number_btn);
}
}
}
I think error is in this code as i am not able to trouble shoot is please help me with this
private void customermenu() {
swipeRefreshLayout.setRefreshing(true);
DatabaseReference databaseReference =
FirebaseDatabase.getInstance().getReference("FoodSupplyDetails")
.child(State).child(City).child(Sub);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
updateDishModelList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
UpdateDishModel updateDishModel =
snapshot1.getValue(UpdateDishModel.class);
updateDishModelList.add(updateDishModel);
}
}
adapter = new CustomerHomeAdapter(getContext(), updateDishModelList);
recyclerView.setAdapter(adapter);
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
swipeRefreshLayout.setRefreshing(false);
}
});
enter image description here
enter image description here
From your code, your issue seems to be on below line:
FirebaseDatabase.getInstance().getReference("FoodSupplyDetails")
.child(State).child(City).child(Sub);
Error tells you you cannot pass null for ".child()". So it is telling you the values for State, City and Sub are null. You can confirm this by going to your Firebase's console database and seeing the data structure for the corresponding "Customer" with the firebase id.
Please check your Firebase database and make sure the customer data exists.
Before you run your query you should make sure the values are not null.
if (State != null && City != null && Sub != null) {
// Run your query here
} else {
Log.d("TAG", "Data provided is null")
}
When you are fetching customer's information, try logging that and check which of them is null:
String State, City, Sub;
//...
State = cust.getState();
City = cust.getCity();
Sub = cust.getSuburban();
Log.d("TAG", State);
Log.d("TAG", City);
Log.d("TAG", Sub);
// call customermenu now
customermenu();
The error tells you you cannot pass null for ".child()". So it is telling you the values for data(stored in the firebase database) are null. You can confirm this by going to your Firebase's console database and seeing the data structure corresponding with the firebase id.
I need to add ClickListener to RecyclerView in my project but I couldn't.
I tried for days and failed :(
Help me, please.
(the variables are in Italian)
RecyclerView class:
public class ListaNonConsegnate extends AppCompatActivity{
private androidx.recyclerview.widget.RecyclerView recyclerView;
EditText searchBox;
DatabaseReference nonConsegnate;
private ArrayList<dati> list;
private String nomeUtente;
private SwipeRefreshLayout swipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_non_consegnate);
Bundle extras = getIntent().getExtras();
nomeUtente = extras.getString("KEY_nomeUtente"); //variable from the previous activity
searchBox = findViewById(R.id.searchBox); //for filtered list
nonConsegnate = FirebaseDatabase.getInstance().getReference().child(nomeUtente + "/00-b-Non consegnate"); //path on the database
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
ArrayList<dati> myList = new ArrayList<>();
//add filter
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
});
}
#Override
protected void onStart() {
super.onStart();
if (nonConsegnate != null) {
nonConsegnate.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
list = new ArrayList<>();
for (DataSnapshot ds : snapshot.getChildren()) {
list.add(ds.getValue(dati.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(ListaNonConsegnate.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Adapter class:
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder>{
ArrayList<dati> list;
public AdapterClass(ArrayList<dati> list){
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_items, viewGroup, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.bolla.setText(list.get(position).getDDT());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView bolla;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
bolla = itemView.findViewById(R.id.textViewBolla);
}
}
}
(OnClick will have to open a new activity by passing it the "nomeUtente" and "DDT" variables)
Thank you.
(StackOverflow tells me I need to add more details but there's nothing more to say so I write useless sentences) lol
1- Add this Code To Your Activity :
public void onClickCalled() {
// Your Code
}
2- and this in your adapter :
holder.nomeUtente.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((YourNewActivity) context).onClickCalled();
}
});
There is a problem with the data displayed in the recyclerview when I run my program
it looks like this:
.
For the data that is displayed I use firebase like this the
data structure:
When I want to display data in recyclerview in a fragment, but the data doesn't appear. I use Firebase as database
NotaAdapter.java
public class NotaAdapter extends RecyclerView.Adapter<NotaAdapter.MyViewHolder> {
Context context;
ArrayList<ListNota> listnota;
public NotaAdapter (Context c,ArrayList<ListNota> p) {
this.context = c;
this.listnota = p;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
return new MyViewHolder(LayoutInflater.from(context)
.inflate(R.layout.item_nota, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.no_nota.setText(listnota.get(i).getId_nota());
myViewHolder.total_harga.setText(String.valueOf(listnota.get(i).getTotal_seluruh()));
final String getnoNOta = listnota.get(i).getId_nota();
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent gotoDetailNota = new Intent(context, DetailNotaAct.class);
gotoDetailNota.putExtra("no_nota", getnoNOta);
context.startActivity(gotoDetailNota);
}
});
}
#Override
public int getItemCount() {
return listnota.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView no_nota, total_harga;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
no_nota = itemView.findViewById(R.id.xid_nota);
total_harga = itemView.findViewById(R.id.xtotal_seluruh);
}
}
}
ListNota.java
public class ListNota {
private String id_nota;
private Integer total_seluruh;
public ListNota() {
}
public ListNota(String id_nota, Integer total_seluruh) {
this.id_nota = id_nota;
this.total_seluruh = total_seluruh;
}
public String getId_nota() {
return id_nota;
}
public void setId_nota(String id_nota) {
this.id_nota = id_nota;
}
public Integer getTotal_seluruh() {
return total_seluruh;
}
public void setTotal_seluruh(Integer total_seluruh) {
this.total_seluruh = total_seluruh;
}
}
HistoryFragment.java
public class HistoryFragment extends Fragment {
TextView txt_history, txt_toko, txt_report, txt_nama_toko, txt_jenis_toko;
LinearLayout btn_buat_nota;
DatabaseReference databaseUser, databaseToko, databaseNota;
String USERNAME_KEY = "usernamekey";
String username_key = "";
String username_key_new = "";
String id_Toko = "";
ProgressDialog progress;
RecyclerView nota_place;
ArrayList<ListNota> list;
NotaAdapter notaAdapter;
private View Notaview;
public HistoryFragment(){
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Notaview = inflater.inflate(R.layout.fragment_history, container, false);
txt_nama_toko = (TextView) Notaview.findViewById(R.id.txt_nama_toko);
txt_jenis_toko = (TextView) Notaview.findViewById(R.id.txt_jenis_toko);
txt_history = (TextView) Notaview.findViewById(R.id.txt_history);
txt_toko = (TextView) Notaview.findViewById(R.id.txt_toko);
txt_report = (TextView) Notaview.findViewById(R.id.txt_report);
btn_buat_nota = (LinearLayout) Notaview.findViewById(R.id.btn_buat_nota);
progress = new ProgressDialog(getActivity());
progress.setTitle("Loading");
progress.setMessage("Memuat Data");
progress.setCancelable(false);
progress.show();
getUsernameLocal();
databaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(username_key_new);
databaseUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
id_Toko = dataSnapshot.child("id_toko").getValue().toString();
databaseToko = FirebaseDatabase.getInstance().getReference().child("Toko").child(id_Toko);
databaseToko.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
txt_nama_toko.setText(dataSnapshot.child("nama_toko").getValue().toString());
//cek apakah child jenis toko ada
if (dataSnapshot.hasChild("jenis_toko")){
txt_jenis_toko.setText(dataSnapshot.child(" jenis_toko").getValue().toString());
}else{
txt_jenis_toko.setText("Jenis toko belum disetting");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
btn_buat_nota.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String id_nota = generateRandomString(16);
Intent gotoBuatNota = new Intent(getActivity(), BuatNotaAct.class);
gotoBuatNota.putExtra("id_nota", id_nota);
startActivity(gotoBuatNota);
}
});
nota_place = (RecyclerView) Notaview.findViewById(R.id.nota_place);
notaAdapter = new NotaAdapter(getContext(), list);
nota_place.setAdapter(notaAdapter);
nota_place.setLayoutManager(new LinearLayoutManager(getActivity()));
return Notaview;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = new ArrayList<ListNota>();
loaddata();
}
private void loaddata(){
databaseNota = FirebaseDatabase.getInstance().getReference().child("Nota").child(id_Toko);
databaseNota.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren()){
ListNota p = dataSnapshot1.getValue(ListNota.class);
list.add(p);
}
progress.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
public String generateRandomString(int length){
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
StringBuilder stringBuilder = new StringBuilder();
Random random = new Random();
for(int i = 0; i < length; i++){
char c = chars[random.nextInt(chars.length)];
stringBuilder.append(c);
}
return stringBuilder.toString();
}
public void getUsernameLocal(){
SharedPreferences sharedPreferences = getActivity().getSharedPreferences(USERNAME_KEY, MODE_PRIVATE);
username_key_new = sharedPreferences.getString(username_key,"");
}
}
you are reading it from the wrong node, you are passing reference that you want to read data from the node Named "users".
Your Database reference should look like this
databaseUser = FirebaseDatabase.getInstance().getReference("Nota").child("Toko_Kita20082020371").child(username_key_new);
Also make sure your list should have all the variables that a node has.
For example a node has
name,id,price,description;
then same varibles should be declared in your list to successfully ready dta from the firebase.
I have an ImageView which acts as a like button and when a user clicks on it, it changes to a different ImageView which indicates that that comment was liked. The problem is that when I click on one, more than one gets selected. Let's say that there are 6 comments in the list and I "like" the 4th comment, other ones get "liked" also which shouldn't happen. The only one that should be getting "liked" is the one I click on. How can I fix this?
CommentAdapter
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final Comment comment = mCommentList.get(position);
holder.comment.setText(comment.getComment());
commentLike(comment.getCommentid(), holder.commentLike);
commentDislike(comment.getCommentid(), holder.commentDislike);
holder.commentLike.setOnClickListener(v -> {
if (holder.commentLike.getTag().equals("like") && holder.commentDislike.getTag().equals("dislike")) {
likeComment(comment.getCommentid(), mPostId, comment.getPublisher());
} else if (holder.commentLike.getTag().equals("like") && holder.commentDislike.getTag().equals("disliked")) {
likeComment(comment.getCommentid(), mPostId, comment.getPublisher());
removeDislike(comment.getCommentid());
} else {
removeLike(comment.getPublisher(), comment.getCommentid());
}
});
holder.commentDislike.setOnClickListener(v -> {
if (holder.commentDislike.getTag().equals("dislike") && holder.commentLike.getTag().equals("like")) {
dislikeComment(comment.getCommentid());
Toast.makeText(mContext, "Don't be mean", Toast.LENGTH_SHORT).show();
} else if (holder.commentDislike.getTag().equals("dislike") && holder.commentLike.getTag().equals("liked")) {
dislikeComment(comment.getCommentid());
removeLike(comment.getPublisher(), comment.getCommentid());
Toast.makeText(mContext, "Don't be mean", Toast.LENGTH_SHORT).show();
} else {
removeDislike(comment.getCommentid());
}
});
holder.itemView.setOnLongClickListener(v -> {
if (comment.getPublisher().equals(mFirebaseUser.getUid())) {
AlertDialog alertDialog = new AlertDialog.Builder(mContext).create();
alertDialog.setTitle("Would you like to delete this comment?");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "No", (dialog, which) -> dialog.dismiss());
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", (dialog, which) -> {
deleteCommentNotification(mPostId, comment.getCommentid());
FirebaseDatabase.getInstance().getReference("Comments Liked").child(comment.getCommentid()).setValue(null);
FirebaseDatabase.getInstance().getReference("Comments Disliked").child(comment.getCommentid()).setValue(null);
FirebaseDatabase.getInstance().getReference("Responses").child(comment.getCommentid()).setValue(null);
Toast.makeText(mContext, "Your comment has been deleted.", Toast.LENGTH_SHORT).show();
dialog.dismiss();
});
alertDialog.show();
}
return true;
});
static class ViewHolder extends RecyclerView.ViewHolder {
CircleImageView image_profile;
TextView username, comment, commentLikesNumber, commentDislikesNumber, commentResponseNumber, timestamp;
ImageView commentLike, commentDislike, iconComment;
ViewHolder(#NonNull View itemView) {
super(itemView);
commentLike = itemView.findViewById(R.id.icon_thumb_up_grey);
commentDislike = itemView.findViewById(R.id.icon_thumb_down_grey);
}
}
private void commentLike(final String commentid, final ImageView imageView) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Liked").child(commentid);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (mFirebaseUser != null)
if (dataSnapshot.child(mFirebaseUser.getUid()).exists()) {
imageView.setImageResource(R.drawable.ic_thumb_up_blue);
imageView.setTag("liked");
} else {
imageView.setImageResource(R.drawable.ic_thumb_up_grey);
imageView.setTag("like");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void commentDislike(final String commentid, final ImageView imageView) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Comments Disliked").child(commentid);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (mFirebaseUser != null)
if (dataSnapshot.child(mFirebaseUser.getUid()).exists()) {
imageView.setImageResource(R.drawable.ic_thumb_down_blue);
imageView.setTag("disliked");
} else {
imageView.setImageResource(R.drawable.ic_thumb_down_grey);
imageView.setTag("dislike");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
CommentsActivity
private void readComments() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments").child(mPostId);
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Comment comment = dataSnapshot.getValue(Comment.class);
try {
comment.setComment(decrypt(comment.getComment(), mPassword));
} catch (Exception e) {
e.printStackTrace();
}
mCommentList.add(comment);
keysList.add(dataSnapshot.getKey());
mCommentAdapter.notifyItemInserted(mCommentList.size() - 1);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
int index = keysList.indexOf(dataSnapshot.getKey());
mCommentList.remove(index);
keysList.remove(index);
mCommentAdapter.notifyDataSetChanged();
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
reference.addChildEventListener(childEventListener);
}
I have seen your code and found that you are making mistake by fetching data from firebase by creating methods in the adapter and calling it from onBindViewHolder.
I am currently working with firebase realtime database and I had faced the same problem like you before 3 months and the solution i have used is working fine.
You should have to use asyncTask inside recycler view adapter. Please have a look at my code, this may help you.
Feel free to ask me if you need any help regarding android and firebase
ChooserAdapter.java
public class ChooserAdapter extends RecyclerView.Adapter<ViewHolder> {
ArrayList<Bean> list;
Context context;
public ChooserAdapter(ArrayList<DoctorList> list, Context context) {
this.listFiltered = list;
this.list = list;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);
ViewHolder holder = new ViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.bean = list.get(position);
holder.asyncTask = new AsyncTask(holder,holder.bean.getId());
holder.asyncTask.execute();
}
#Override
public int getItemCount() {
return list.size();
}
public ArrayList<List> adapterList() {
return list;
}
public List getItem(int position) {
return list.get(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.txtTitle)
TextView txtTitle;
AsyncTask asyncTask;
Bean bean;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
static class AsyncTask extends AsyncTask<Void, Integer, String> {
ViewHolder viewHolder;
String Id;
DatabaseReference dbRef;
AsyncTask(ViewHolder viewHolder, String Id) {
this.viewHolder = viewHolder;
this.Id = Id;
dbRef = FirebaseDatabase.getInstance().getReference("FcmNode");
dbRef.keepSynced(true);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... voids) {
if (!isCancelled())
dbRef.orderByChild("Id").equalTo(Id).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String name = dataSnapshot.getValue(String.class);
viewHolder.txtTitle.setText(name);
viewHolder.txtTitle.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return "";
}
#Override
protected void onPostExecute(String data) {
super.onPostExecute(data);
}
}
}
I'm developing an android app where the details from the Firebase Realtime Database will be shown in Recycler View.
I want to make it like expandable recyclerview.
But I'm getting a error when i tried to use my adapter.
Variable 'adapter' might not have been initialised
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions options =
new FirebaseRecyclerOptions.Builder<Employee>()
.setQuery(mAttendanceDatabase, Employee.class)
.build();
final FirebaseRecyclerAdapter<Employee, EmployeeViewHolder> adapter = new FirebaseRecyclerAdapter<Employee, EmployeeViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final EmployeeViewHolder holder, final int position, #NonNull Employee model) {
String employee_Id = getRef(position).getKey();
assert employee_Id != null;
mAttendanceDatabase.child(employee_Id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String employee_Name = dataSnapshot.child("employeeName").getValue().toString();
holder.employeeName.setText(employee_Name);
holder.btn_viewMore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.getItem(position); //I'm getting error here
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
}
});
}
#NonNull
#Override
public EmployeeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.employee_view_layout, parent, false);
EmployeeViewHolder viewHolder = new EmployeeViewHolder(view);
return viewHolder;
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
public static class EmployeeViewHolder extends RecyclerView.ViewHolder{
TextView employeeName;
ImageButton btn_viewMore;
public EmployeeViewHolder(#NonNull View itemView) {
super(itemView);
employeeName = itemView.findViewById(R.id.employeeName_evl);
btn_viewMore = itemView.findViewById(R.id.viewMoreBtn);
}
}
I can't find any proper solution. Help me with this.
try to put the adapter over this in a variable:
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions options =
new FirebaseRecyclerOptions.Builder<Employee>()
.setQuery(mAttendanceDatabase, Employee.class)
.build();
final FirebaseRecyclerAdapter<Employee, EmployeeViewHolder> adapter = new FirebaseRecyclerAdapter<Employee, EmployeeViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final EmployeeViewHolder holder, final int position, #NonNull Employee model) {
String employee_Id = getRef(position).getKey();
assert employee_Id != null;
final FirebaseRecyclerAdapter<Employee, EmployeeViewHolder> thisAdapter = this;
mAttendanceDatabase.child(employee_Id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String employee_Name = dataSnapshot.child("employeeName").getValue().toString();
holder.employeeName.setText(employee_Name);
holder.btn_viewMore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
thisAdapter.getItem(position); //I'm getting error here
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
}
});
}
#NonNull
#Override
public EmployeeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.employee_view_layout, parent, false);
EmployeeViewHolder viewHolder = new EmployeeViewHolder(view);
return viewHolder;
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
Edit
To support my case I made a minimal Example: