0

I have 2 collections (Customer, Order) like below:

  • Customer has fields:

    • address
    • name
    • phone
  • Order collection has 3 fields

    • cost
    • customerId
    • date
    • orderName

I attached 2 collection table as the attachment at the end of page

Now I want to build a list of orders with FirestoreRecyclerAdapter (notice that, this list order will show customer name as well). It means that, inside the OrderAdapter, I have to query customer name by customerId.

This is the code of OrderAdapter:

public class OrderAdapter extends FirestoreRecyclerAdapter<OrderInfo, OrderAdapter.OrderHolder> implements Constant {
    private FirebaseFirestore mDatabase = FirebaseFirestore.getInstance();
    private DocumentReference mDocRef;

    private OrderItemClickCallback mListener;

    public OrderAdapter(@NonNull FirestoreRecyclerOptions<OrderInfo> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull final OrderHolder holder, final int position, @NonNull OrderInfo model) {
        holder.txtTitle.setText(model.getOrderName());
        holder.txtDate.setText(model.getDate());
        holder.txtCost.setText(String.valueOf(model.getCost()));

        //Because customer name belongs to Customer collection, so that I have to query the customer name by customerId
        //However, this query will be done in another thread, so that when shows on the Order list, the customer name will be shown slower, 
        //and the customer name will be shown after other Order fields (other fields like orderName, date, cost)
        mDocRef = mDatabase.collection("User").document(Constant.USER_ID).collection("Customer").document(model.getCustomerid());
        mDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if(task.isSuccessful()){
                    DocumentSnapshot doc = task.getResult();
                    if(doc.exists()){
                        String name = doc.get(NAME).toString();
                        holder.txtCusName.setText(name);
                    }
                }
            }
        });
    }

    @NonNull
    @Override
    public OrderHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_order, parent, false);
        return new OrderHolder(view);
    }


    class OrderHolder extends RecyclerView.ViewHolder{
        TextView txtCusName;
        TextView txtOrderName;
        TextView txtDate;
        TextView txtCost;


        public OrderHolder(@NonNull View itemView) {
            super(itemView);
            txtCusName = itemView.findViewById(R.id.txt_customer_name);
            txtOrderName = itemView.findViewById(R.id.txt_order_name);
            txtDate = itemView.findViewById(R.id.txt_date);
            txtCost = itemView.findViewById(R.id.txt_cost);
        }
    }

Because customer name belongs to Customer collection, so that I have to query the customer name by customerId insdide the adapter.

But it has 2 bugs:

  1. This query will be done in another thread, so that when shows on the Order list, the customer name will be shown slower than other Order fields (Order name, cost, date)

  2. When the list shown for the first time, then it is correct. But when I scroll down/up then the customer name display incorrectly.

Any one can help me these bugs 1 and 2. And do you know the way to query data from 2 Collection efficiently?

Order collection

Customer collection

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Bean
  • 23
  • 6
  • That #1 looks like the expected behavior, and not a bug. If you want a different behavior, describe how you want it to work (realizing that we can't change the nature of asynchronous code). – Frank van Puffelen Jun 24 '20 at 14:42
  • Do you have any suggestions to sync this to show all Fields on item at the same time (Order name, cost, date, customer name)? Currently when the list item shown, 3 fields of Order collection (order name, date, cost) first, then customer name is shown later (delay ~500ms) , it is not good – Bean Jun 24 '20 at 16:01
  • That means you shouldn't render the item until the customer name is also loaded. You could [hide the item](https://stackoverflow.com/questions/41223413/how-to-hide-an-item-from-recycler-view-on-a-particular-condition) until then, or only add it later (but that might lead to them being reordered in the view). – Frank van Puffelen Jun 24 '20 at 18:17

0 Answers0