I am new to android studio and currently watching tutorials. As of now I have a Shopping cart activity where I can increment, decrement and delete items in cart. The thing is whenever I delete, add or deduct an item, the cart values does not update. I still need to change activities to see the changes. Also the item that I deleted still appears at the bottom of recyclerview items after the dialog appearance unless I change the activity and go back. Please help me how to apply real time update. Below are my class files for the cart activity and adapter class.
CartActivity.java
#Override
protected void onStop() {
if (EventBus.getDefault().hasSubscriberForEvent(MyUpdateCartEvent.class))
EventBus.getDefault().removeStickyEvent(MyUpdateCartEvent.class);
EventBus.getDefault().unregister(this);
super.onStop();
}
#Subscribe(threadMode = ThreadMode.MAIN_ORDERED, sticky = true)
public void onUpdateCart(MyUpdateCartEvent event) {
loadCartFromFirebase();
}
private void loadCartFromFirebase() {
fAuth = FirebaseAuth.getInstance();
if(fAuth.getCurrentUser() != null){
userId = fAuth.getCurrentUser().getUid();
} else {
userId = "UNIQUE_USER_ID";
}
List<CartModel> cartModels = new ArrayList<>();
FirebaseDatabase.getInstance()
.getReference("cart")
.child(userId)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
for (DataSnapshot cartSnapshot : snapshot.getChildren()) {
CartModel cartModel = cartSnapshot.getValue(CartModel.class);
cartModel.setKey(cartSnapshot.getKey());
cartModels.add(cartModel);
}
cartLoadListener.onCartLoadSuccess(cartModels);
} else {
cartLoadListener.onCartLoadFailed("Cart Empty");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
cartLoadListener.onCartLoadFailed(error.getMessage());
}
});
}
private void init() {
ButterKnife.bind(this);
cartLoadListener = this;
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycler_cart.setLayoutManager(layoutManager);
purchScrnBtn.setOnClickListener(v -> startActivity(new Intent(this, PurchaseActivity.class)));
}
#Override
public void onCartLoadSuccess(List<CartModel> cartModelList) {
double sum = 0;
for (CartModel cartModel : cartModelList) {
sum += cartModel.getTotalPrice();
}
textTotal.setText(new StringBuilder("$").append(sum));
MyCartAdapter adapter = new MyCartAdapter(this, cartModelList);
recycler_cart.setAdapter(adapter);
}
MyCartAdapter.java
package com.example.cart.adapter;
public class CartActivity extends AppCompatActivity implements CartLoadListener {
public MyCartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyCartViewHolder(LayoutInflater.from(context)
.inflate(R.layout.layout_cart_item, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyCartViewHolder holder, int position) {
holder.minus.setOnClickListener(v -> {
minusCartItem(holder,cartModelList.get(position));
});
holder.delete.setOnClickListener(v -> {
AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("Delete item")
.setMessage("Do you really want to delete item")
.setNegativeButton("CANCEL", (dialogInterface, i) -> dialogInterface.dismiss())
.setPositiveButton("OK", (dialogInterface2, i) -> {
//Temp remove
notifyItemRemoved(position);
deleteFromFirebase(cartModelList.get(position));
dialogInterface2.dismiss();
}).create();
dialog.show();
});
}
private void deleteFromFirebase(CartModel cartModel) {
FirebaseDatabase.getInstance()
.getReference("cart")
.child(userId)
.child(cartModel.getKey())
.removeValue()
.addOnSuccessListener(aVoid -> EventBus.getDefault().postSticky(new MyUpdateCartEvent()));
}
#SuppressLint("SuspiciousIndentation")
private void minusCartItem(MyCartViewHolder holder, CartModel cartModel) {
if(cartModel.getQuantity() > 1)
cartModel.setQuantity(cartModel.getQuantity()-1);
cartModel.setTotalPrice(cartModel.getQuantity()*Float.parseFloat(cartModel.getPrice()));
//update quantity
holder.txtQuantity.setText(new StringBuilder().append(cartModel.getQuantity()));
updateFirebase(cartModel);
}
public class MyCartViewHolder extends RecyclerView.ViewHolder{
Unbinder unbinder;
public MyCartViewHolder(#NonNull View itemView) {
super(itemView);
unbinder = ButterKnife.bind(this, itemView);
}
}
}
The thing is whenever I delete, add or deduct an item, the cart values does not update.
That's because you load data from Firebase with addListenerForSingleValueEvent, which only loads the data when you call it. If you want to continue to monitor the data for changes, use addValueEventListener instead.
Related
I would like to refresh my recycle view when a user taps a button, the problem is my recycle view is inside a fragment, and my user interface is being updated from my OnBindViewHolder method. So, my question is how do you call a method that's inside a fragment, from an Adapter. I would like to call my downloadCartData() from my Cart_Fragment when the user clicks on plusImageView from my adapter. I found some answers on stack overflow that says to use an interface, but I don't understand what's happening or how to apply it to my code.
public class CartAdapter extends RecyclerView.Adapter<CartAdapter.ViewHolder> {
private List<CartModel> cartArrayList;
private Context ct;
public int count = 1;
private String loggedInUserId;
public CartAdapter(List<CartModel> cartArrayList, Context ct) {
this.cartArrayList = cartArrayList;
this.ct = ct;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") final int position) {
holder.produceName.setText(cartArrayList.get(position).getProductName());
Log.i("productname", cartArrayList.get(position).getProductName());
holder.producePrice.setText("$" + cartArrayList.get(position).getItemPrice());
holder.plusImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
// Cart_Fragment cart_fragment = new Cart_Fragment();
// cart_fragment.callMethod();
//
}
}
});
}
});
//Log.i("IMAGES", productArrayList.get(position).getProductImage());
Glide.with(ct)
.load(cartArrayList.get(position).getProductImage())
.centerCrop()
.into(holder.productImage);
}
#Override
public int getItemCount() {
return cartArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView produceName, producePrice, middleQUanityTv;
private ImageView productImage, plusImageView, minusImageView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
produceName = itemView.findViewById(R.id.itemNameTv);
producePrice = itemView.findViewById(R.id.priceTv);
productImage = itemView.findViewById(R.id.productImageView);
plusImageView = itemView.findViewById(R.id.plusImageView);
middleQUanityTv = itemView.findViewById(R.id.middleQuanaityTv);
}
}
//hide ui elements here..
public void getCurrentUserUid() {
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
loggedInUserId = firebaseUser.getUid(); //Do what you need to do with your uid
Log.i("loggedInUserUid", loggedInUserId);
}
}
}
public void downloadCartData() {
cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
if (data.exists()) {
//get the item prices to add to hashmap.
String price = data.child("itemPrice").getValue().toString();
String quantity = data.child("quantity").getValue().toString();
priceArrayList.add(price);
quantityArrayList.add(quantity);
cartModel = data.getValue(CartModel.class);
cartModelArrayList.add(cartModel);
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
cartRecyleView.setLayoutManager(horizontalLayoutManager);
cartAdapter = new CartAdapter(cartModelArrayList, getContext());
cartRecyleView.setAdapter(cartAdapter);
} else {
Log.i("error", "Error Loading JSON data..");
}
}
calculatePrice(priceArrayList, quantityArrayList);
Log.i("priceArrayList", priceArrayList + "");
Log.i("quanityArrayList", quantityArrayList + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
String error = databaseError.getDetails();
Log.i("error", error);
}
});
}
You have heard right from the other stack overflow posts that you can use interface to call the method of the fragment from the adapter.
First you have to create a interface and define the method name in the
interface.
interface DownloadCart{
void downloadCartData();
}
After creating this interface you need to implement this interface
into the fragment where your recycler view is declared.
class Cart_Fragment implements DownloadCart{
After implementing this interface into the class it will show you red
line in android studio. it will require to add the method of the
interface into your fragment. add your code of the
downloadCartData into this interface method body in your fragment.
void downloadCartData(){
cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
if (data.exists()) {
//get the item prices to add to hashmap.
String price = data.child("itemPrice").getValue().toString();
String quantity = data.child("quantity").getValue().toString();
priceArrayList.add(price);
quantityArrayList.add(quantity);
cartModel = data.getValue(CartModel.class);
cartModelArrayList.add(cartModel);
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
cartRecyleView.setLayoutManager(horizontalLayoutManager);
cartAdapter = new CartAdapter(cartModelArrayList, getContext());
cartRecyleView.setAdapter(cartAdapter);
} else {
Log.i("error", "Error Loading JSON data..");
}
}
calculatePrice(priceArrayList, quantityArrayList);
Log.i("priceArrayList", priceArrayList + "");
Log.i("quanityArrayList", quantityArrayList + "");
}
#Override
public void onCancelled(DatabaseError databaseError) {
String error = databaseError.getDetails();
Log.i("error", error);
}
});
}
Create on object of the interface into your adapter.
DownloadCart inf;
Define your adapter constructor like this and pass your interface
object into the adapter call.
public CartAdapter(List<CartModel> cartArrayList, Context ct, DownloadCart inf) {
this.cartArrayList = cartArrayList;
this.ct = ct;
this.inf = inf;
}
After that on bind view holder call your fragment method into the
adapter by using the interface object. it will call the method from
the fragment.
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") final int position) {
holder.produceName.setText(cartArrayList.get(position).getProductName());
Log.i("productname", cartArrayList.get(position).getProductName());
holder.producePrice.setText("$" + cartArrayList.get(position).getItemPrice());
holder.plusImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
inf.downloadCartData();
}
}
});
}
});
//Log.i("IMAGES", productArrayList.get(position).getProductImage());
Glide.with(ct)
.load(cartArrayList.get(position).getProductImage())
.centerCrop()
.into(holder.productImage);
}
Tadaaa!!! and your method from fragment is called from adapter.
Pass the Cart_Fragment inside your adapter Constructor, then simply call the method you're trying to reference from your onClickListener by referencing the passed Fragment.
private Cart_Fragment cart_fragment = new Cart_Fragment();
public CartAdapter(List<CartModel> cartArrayList, Context ct, Cart_Fragment cart_fragment) {
this.cartArrayList = cartArrayList;
this.ct = ct;
this.cart_fragment = cart_fragment;
}
#Override
public void onClick(View view) {
getCurrentUserUid();
count = count + 1;
FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
holder.middleQUanityTv.setText(count + "");
Cart_Fragment cart_fragment = new Cart_Fragment();
cart_fragment.callMethod();
}
}
});
}
});
public class ChatFragment extends Fragment {
View chatview;
String CurrentUserID;
FirebaseAuth auth;
String time , date ,CurrentDate;
RecyclerView recyclerView;
DatabaseReference ContactRef,UserRef;
FloatingActionButton floatingActionButton;
List<Contacts> contacts;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
chatview =inflater.inflate(R.layout.fragment_chat, container, false);
auth= FirebaseAuth.getInstance();
CurrentUserID=auth.getCurrentUser().getUid();
ContactRef= FirebaseDatabase.getInstance().getReference().child("Contacts").child(CurrentUserID);
UserRef= FirebaseDatabase.getInstance().getReference().child("Users");
recyclerView=chatview.findViewById(R.id.chat_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
floatingActionButton=chatview.findViewById(R.id.chat_float_btn);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SendtoFindFriendsActivity();
}
});
return chatview;
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Contacts> options=new FirebaseRecyclerOptions.Builder<Contacts>()
.setQuery(ContactRef,Contacts.class)
.build();
FirebaseRecyclerAdapter<Contacts,ChatViewHolder> adapter=new FirebaseRecyclerAdapter<Contacts, ChatViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ChatViewHolder holder, #SuppressLint("RecyclerView") int position, #NonNull Contacts model) {
String userid=getRef(position).getKey();
final String[] image = {""};
final String[] name = {""};
UserRef.child(userid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild("image"))
{
image[0] =snapshot.child("image").getValue().toString();
GetImage(image[0], holder.profileImage );
}
name[0] =snapshot.child("name").getValue().toString();
holder.lastSeen.setText("Date"+"Time");
holder.userName.setText(name[0]);
holder.userStatus.setText(snapshot.child("status").getValue().toString());
holder.lastSeen.setVisibility(View.VISIBLE);
if (snapshot.child("userState").hasChild("state"))
{
String state=snapshot.child("userState").child("state").getValue().toString();
date=snapshot.child("userState").child("date").getValue().toString();
time=snapshot.child("userState").child("time").getValue().toString();
if (state.equals("online"))
{
holder.lastSeen.setVisibility(View.INVISIBLE);
holder.online.setVisibility(View.VISIBLE);
}
else if (state.equals("offline"))
{
holder.lastSeen.setVisibility(View.VISIBLE);
holder.online.setVisibility(View.INVISIBLE);
Calendar calendar=Calendar.getInstance();
SimpleDateFormat dateFormat=new SimpleDateFormat("MMM dd,yyyy");
CurrentDate=dateFormat.format(calendar.getTime());
if (CurrentDate.equals(date))
{
holder.lastSeen.setText(time.toLowerCase(Locale.ROOT));
}
else
{
holder.lastSeen.setText(date);
}
}
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent chat=new Intent(getActivity(), ChatActivity.class);
chat.putExtra("uid",userid);
chat.putExtra("name",name[0]);
chat.putExtra("image",image[0]);
startActivity(chat);
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#NonNull
#Override
public ChatViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.user_display_layout,parent,false);
ChatViewHolder viewHolder=new ChatViewHolder(view);
return viewHolder;
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
public static class ChatViewHolder extends RecyclerView.ViewHolder
{
TextView userName,userStatus,lastSeen;
CircleImageView profileImage;
ImageView online;
public ChatViewHolder(#NonNull View itemView) {
super(itemView);
userName=itemView.findViewById(R.id.user_profile_name);
userStatus=itemView.findViewById(R.id.user_profile_status);
profileImage=itemView.findViewById(R.id.users_profile_image);
userStatus.setVisibility(View.VISIBLE);
lastSeen=itemView.findViewById(R.id.user_profile_lastseen);
lastSeen.setVisibility(View.VISIBLE);
online=itemView.findViewById(R.id.online_icon);
}
}
private void SendtoFindFriendsActivity() {
Intent intent=new Intent(getActivity(), FindFriends.class);
startActivity(intent);
}
private void GetImage(String currentUser, CircleImageView imageView) {
StorageReference storageReference = FirebaseStorage.getInstance().getReference().
child("Profile Images/" + currentUser + ".jpg");
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Glide.with(getContext()).load(uri).into(imageView);
}
});
}
}
can anyone tell me how Can I remove an item from firebase recyclerview .I am new in java app development that's why I am facing problem.
can anyone tell me how Can I remove an item from firebase recyclerview .I am new in java app development that's why I am facing problem.can anyone tell me how Can I remove an item from firebase recyclerview .I am new in java app development that's why I am facing problem.
If I'm understanding the adapter (FirebaseRecyclerAdapter) correctly, it will always display the designated documents in the recyclerView, so in order to remove an item from that list, you'll need to delete it from the database (in your case 'Realtime Database'). Otherwise, anytime you'll remove it from the list localy, the adapter will quicly put it back in.
So in order to remove an item from this list my approach will be:
Assuming we need to delete a single item at a time (and not a batch of items)
figure out how to impliment the desired UI\UX element that will start the delete proccess.
echo the corresponding UID of the item to the viewmodel
delete the item from the database via the viewmodel
echo back to the front the operation result in-order to provide some feedback to the user (a popup displaying: "item removed!", "connection error" and such)
If I'm not mistaken, after the item is removed from the database, the adapter should automatically remove it from the list displayed to the user.
If it dosen't work, or this solution is sub-optimal for your specific endeavour i think you'll have no choice but to make your own adapter.
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.
So i have a recycler view that is designed to show users sending messages to each other from my Firebase RTD. Originally it was working to show all users and the recycler items were clicked then it would show messages between the users. However, when modifying it to only view users that were in open messages with the current user, the items that populated my recycler view no longer displays and an error saying E/RecyclerView: No adapter attached; skipping layout is logged within the Run tab.
Unfortunately i can no longer undo the changes and have struggled to find the cause of my problem but have assume that it is either taking place in my adapted or activity classes.
InboxActivity.java:
public class InboxActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<User> inboxLst;
FirebaseUser user;
DatabaseReference reference;
UserAdapter usrAdpt;
private List<String> userLst;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inbox);
//Identify and setup recycler view
recyclerView = findViewById(R.id.rycInbox);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
userLst = new ArrayList<>();
//Get all chats between current user and and other users
user = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userLst.clear();
for (DataSnapshot snp : dataSnapshot.getChildren()){
Chat chat = snp.getValue(Chat.class);
if (chat.getSender().equals(user.getUid())){
userLst.add(chat.getReceiver());
}
if (chat.getReceiver().equals(user.getUid())){
userLst.add(chat.getSender());
}
}
readChat();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readChat() {
inboxLst = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userLst.clear();
for (DataSnapshot snp : dataSnapshot.getChildren()) {
User usr = snp.getValue(User.class);
//Display users that are currently in an open chat
for (String id : userLst){
if(usr.getId().equals(id)){
if(inboxLst.size() != 0){
for (User usrl : inboxLst){
if(!usr.getId().equals(usrl.getId())){
inboxLst.add(usr);
}
}
}else{
inboxLst.add(usr);
}
}
}
}
//Set the adapter for the recycler view once using the chat information retrieved from firebase database
usrAdpt = new UserAdapter(InboxActivity.this,inboxLst);
recyclerView.setAdapter(usrAdpt);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
}
UserAdapter.java:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
private Context cont;
private List<User> nUser;
public UserAdapter(Context cont, List<User> nUser){
this.cont = cont;
this.nUser = nUser;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(cont).inflate(R.layout.lst_layout_inbox, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
User user = nUser.get(position);
holder.username.setText(user.getUsername());
holder.usrLst.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(cont, MessageActivity.class);
intent.putExtra("userid",user.getId());
cont.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return nUser.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView username;
RelativeLayout usrLst;
public ViewHolder(View itemView){
super(itemView);
username = itemView.findViewById(R.id.usrName);
usrLst = itemView.findViewById(R.id.usrCard);
}
}
}
The only catchup in your question is, in the following method:
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userLst.clear(); // <------ WHY YOU CLEAR LIST HERE??? COMMENT THIS ----------
for (DataSnapshot snp : dataSnapshot.getChildren()) {
User usr = snp.getValue(User.class);
//Display users that are currently in an open chat
for (String id : userLst){
if(usr.getId().equals(id)){
if(inboxLst.size() != 0){
for (User usrl : inboxLst){
if(!usr.getId().equals(usrl.getId())){
inboxLst.add(usr);
}
}
}else{
inboxLst.add(usr);
}
}
}
}
//Set the adapter for the recycler view once using the chat information retrieved from firebase database
usrAdpt = new UserAdapter(InboxActivity.this,inboxLst);
recyclerView.setAdapter(usrAdpt);
}
why you do userLst.clear(); ?
Since in OnCreate() method you populate userLst and call readChat(). And in onDataChange() you clear the userLst and then afterwards you try to iterate over the userLst to Display users that are currently in an open chat.
I would suggest to comment this userLst.clear(); and after setting items call notifyDataSetChanged()
Try these things:
Set the adapter in onCreate.
and in the onDataChanged listener, update the ArrayList and call notifyDataSetChanged().
This should help
Please help me. I want to show the username only once from firebase. Although the user have multiple record in the firebase, I just want to view the name of user who make order. The user can make multiple order, but I just want to show their name once.
I tried many ways but can't succeed. Someone who know about this? Thank you very much.
public void onCreate(Bundle savedInstanceState) {
UID = this.getArguments().getString("UID");
mDatabase = FirebaseDatabase.getInstance().getReference();
mStorage = FirebaseStorage.getInstance();
mItems = new ArrayList<>();
wordDulicate = new ArrayList<>();
tempList = new ArrayList<>();
if(UID != null){
mItemsKey = new ArrayList<>();
mOrderedItemRef = mDatabase.child("OrderedItem");
Log.d(TAG, " mOrderedItemRef:" + mOrderedItemRef);
mOrderedItemVEL = mOrderedItemRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mItems.clear();
mItemsKey.clear();
wordDulicate.clear();
Log.d(TAG, "onDataChange");
for (DataSnapshot d : dataSnapshot.getChildren()) {
OrderedItem orderedItem = d.getValue(OrderedItem.class);
Log.d(TAG, "orderedItem:" + orderedItem.getUserName());
mItems.add(orderedItem);
mItemsKey.add(d.getKey());
}
updateUI();
}
#Override
public void onCancelled (DatabaseError databaseError){
Log.d(TAG, "get item databaseError: "+databaseError);
}
});
}
else{
Log.d(TAG, "UID: "+UID);
}
super.onCreate(savedInstanceState);
}
#Override
public void onDestroy(){
super.onDestroy();
// if (mItemRef != null) mItemRef.removeEventListener(mItemVEL);
}
#Override
public void onDetach(){
super.onDetach();
// if (mItemRef != null) mItemRef.removeEventListener(mItemVEL);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_admin_list_user_order, container, false);
mItemRecyclerView = (RecyclerView) view.findViewById(R.id.admin_order_recycler_view);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mItemRecyclerView.getContext(), new LinearLayoutManager(getActivity()).getOrientation());
mItemRecyclerView.addItemDecoration(dividerItemDecoration);
mItemRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
private void updateUI(){
Log.d(TAG, "Enter updateUI(); mItems: " + mItems);
mAdapter = new ItemAdapter(mItems);
mItemRecyclerView.setAdapter(mAdapter);
}
private class ItemHolder extends RecyclerView.ViewHolder{
OrderedItem mItems;
TextView mNameTextView;
ItemHolder(final View itemView){
super(itemView);
mNameTextView = (TextView) itemView.findViewById(R.id.textview_username);
/* if (UID != null) {
itemView.setOnClickListener(new View.OnClickListener() {
#SuppressLint("LongLogTag")
#Override
public void onClick(View view) {
Log.d(TAG, "UID != null");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder
.setMessage("Delete This Item?")
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
deleteItem(mItems);
}
}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
}*/
}
void bindData(OrderedItem s){
mItems = s;
mNameTextView.setText(s.getUserName());
}
}
private class ItemAdapter extends RecyclerView.Adapter<ItemHolder>{
private ArrayList<OrderedItem> mItems;
ItemAdapter(ArrayList<OrderedItem> Items){
mItems = Items;
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.admin_listed_user_order,parent,false);
return new ItemHolder(view);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
OrderedItem s = mItems.get(position);
holder.bindData(s);
}
#Override
public int getItemCount() {
return mItems.size();
}
}
}
Since you rely on a key and a value, why not use a map instead? Maps have a key and a value, and you can check whether or not an item with a key is present by getting the key, instead of having to iterate through the list and find duplicates.
First you need to initialize it:
Map<String, ArrayList<OrderedItem>> items = new HashMap<>();
The value is an ArrayList to keep any existing data
then put the items:
for (DataSnapshot d : dataSnapshot.getChildren()) {
OrderedItem orderedItem = d.getValue(OrderedItem.class);
Log.d(TAG, "orderedItem:" + orderedItem.getUserName());
items.putIfAbsent(d.getKey(), new ArrayList<>());//create a list if it doesn't exist
items.get(d.geyKey()).add(orderedItem);//add the item
}
and clearing with a map is the same as with lists