Steve Kamau
Steve Kamau

Reputation: 2785

Using Firebase in ListView displays only one row

I know I know this is probably a duplicate of a few questions here, but hey, those solutions haven't worked. So i really need suggestions. Been trying to use firebase to manage my listview but to no avail. I have tried several tutorials around but none has solved my problem. I have a listview which i'm trying to populate from Firebase. I created a custom adapter and added childEventListeners there. Finaly i attach the adapter to my listview. I have several items in my firebase database but only the last one is displayed in my listview.I would like to display all of them.

FireBaseListAdapter.java:

public abstract class FireBaseListAdapter extends ArrayAdapter<SaleModel> {

    Activity activity;
    // Setup our Firebase mFirebaseRef
    DatabaseReference mRef;
    private SaleModel model;
    private String mUsername;
    private LayoutInflater mInflater;
    private List<SaleModel> mModels;
    private List<String> mKeys;
    private ChildEventListener mListener;
    private ViewGroup viewGroup;
    private LinearLayout wrapper;

    public FireBaseListAdapter(DatabaseReference mRef, Activity activity) {
        super(activity, android.R.layout.simple_list_item_1);
        this.activity = activity;
        this.mRef = mRef;
        this.mUsername = mUsername;

        mInflater = activity.getLayoutInflater();
        mModels = new ArrayList<SaleModel>();
        mKeys = new ArrayList<String>();


        // Look for all child events. We will then map them to our own internal ArrayList, which backs ListView
        mListener = this.mRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {

                Map<String, Object> newPost =
                        (Map<String, Object>) dataSnapshot.getValue();
                model = new SaleModel(newPost.get("name").toString(),
                        newPost.get("attendant_name").toString(),
                        newPost.get("created_at").toString());
                String key = dataSnapshot.getKey();

                // Insert into the correct location, based on previousChildName
                if (previousChildName == null) {
                    mModels.add(0, model);
                    mKeys.add(0, key);

                } else {
                    int previousIndex = mKeys.indexOf(previousChildName);
                    int nextIndex = previousIndex + 1;
                    if (nextIndex == mModels.size()) {
                        mModels.add(model);
                        mKeys.add(key);

                    } else {
                        mModels.add(nextIndex, model);
                        mKeys.add(nextIndex, key);
                        //showNotification(model);
                    }
                }

                notifyDataSetChanged();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                // One of the mModels changed. Replace it in our list and name mapping
                String key = dataSnapshot.getKey();
                Map<String, Object> newPost =
                        (Map<String, Object>) dataSnapshot.getValue();

                SaleModel newModel = new SaleModel(newPost.get("message").toString(), newPost.get("author").toString(), newPost.get("created_at").toString());
                int index = mKeys.indexOf(key);

                mModels.set(index, newModel);

                notifyDataSetChanged();
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

                // A model was removed from the list. Remove it from our list and the name mapping
                String key = dataSnapshot.getKey();
                int index = mKeys.indexOf(key);

                mKeys.remove(index);
                mModels.remove(index);

                notifyDataSetChanged();
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {

                // A model changed position in the list. Update our list accordingly
                String key = dataSnapshot.getKey();
                Map<String, Object> newPost =
                        (Map<String, Object>) dataSnapshot.getValue();

                SaleModel newModel = new SaleModel(newPost.get("message").toString(), newPost.get("author").toString(), newPost.get("created_at").toString());
                int index = mKeys.indexOf(key);
                mModels.remove(index);
                mKeys.remove(index);
                if (previousChildName == null) {
                    mModels.add(0, newModel);
                    mKeys.add(0, key);
                } else {
                    int previousIndex = mKeys.indexOf(previousChildName);
                    int nextIndex = previousIndex + 1;
                    if (nextIndex == mModels.size()) {
                        mModels.add(newModel);
                        mKeys.add(key);
                    } else {
                        mModels.add(nextIndex, newModel);
                        mKeys.add(nextIndex, key);
                    }
                }
                notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.e("FireBaseListAdapter", "Listen was cancelled, no more updates will occur");

            }


        });
    }

    public void cleanup() {
        // We're being destroyed, let go of our mListener and forget about all of the mModels
        mRef.removeEventListener(mListener);
        mModels.clear();
        mKeys.clear();
    }

    @Override
    public int getCount() {
        return mModels.size();
    }

    @Override
    public SaleModel getItem(int i) {
        return mModels.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        SaleModel comment = getItem(position);

        int type = getItemViewType(position);

        // Map a Chat object to an entry in our listview
        String author = comment.getName();
        String attendant_name = comment.getAttendant_name();
        String created_at = comment.getCreated_at();

        // If the message was sent by this user, color it differently
        LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService
                (this.activity.getApplicationContext().LAYOUT_INFLATER_SERVICE);

        row = inflater.inflate(R.layout.itemview, parent, false);
        ((TextView) row.findViewById(R.id.attname)).setText(attendant_name);
        ((TextView) row.findViewById(R.id.c_name)).setText(author);
        ((TextView) row.findViewById(R.id.updated_at)).setText(created_at);

        return row;

    }
}

SaleModel.java:

public class SaleModel {
  //obviously there's a lot of things i'm not using here, so ignore these
    String id, business_id, attendant_id, attendant_name, product_id,
            customer_id, customer_first_name, code,
            customer_last_name, customer_image, uid,
            reader_id, price, quantity, name, image,
            created_at, deleted_at, offlineTag, updated_at, svg;
 public SaleModel() {
    }

    public SaleModel(String name, String attendant_name, String created_at) {
        this.name = name;
        this.attendant_name = attendant_name;
        this.created_at = created_at;
    }
//getters and setters
 public String getAttendant_name() {
        return attendant_name;
    }

    public void setAttendant_name(String attendant_name) {
        this.attendant_name = attendant_name;
    }
 public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
  public String getCreated_at() {
        return created_at;
    }

    public void setCreated_at(String created_at) {
        this.created_at = created_at;
    }}

And this is how i'm using it on my fragment:

 @Override
    public void onStart() {
        super.onStart();
   FirebaseDatabase ref = FirebaseDatabase.getInstance().getReference().child("sales");
        setUpAdapter();
       final FireBaseListAdapter mChatListAdapter = new FireBaseListAdapter(ref, parentActivity) {
            @Override
            public void cleanup() {
                super.cleanup();
            }
        };
        listView.setAdapter(mChatListAdapter);
        mChatListAdapter.registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                listView.setSelection(mChatListAdapter.getCount() - 1);
            }
        });

    }

And an example of my data Structure:

{
  "-KMjcAb5O2MOx_WrofUT" : {
    "attendant_id" : "93",
    "business_id" : "9",
    "code" : "9.146860413464",
    "created_at" : "2016-07-15 08:32:10",
    "customer_first_name" : "Unidentified",
    "customer_id" : "10",
    "customer_last_name" : "",
    "image" : "",
    "name" : "Black Forest Cake 2kg",
    "price" : "3500.0",
    "product_id" : "59",
    "quantity" : "1",
    "reader_id" : "93",
    "uid" : ""
  },
  "-KMjcAb8EQi3ujTpoJG1" : {
    "attendant_id" : "93",
    "business_id" : "9",
    "code" : "9.146860413465",
    "created_at" : "2016-07-15 08:32:10",
    "customer_first_name" : "Unidentified",
    "customer_id" : "10",
    "customer_last_name" : "",
    "image" : "",
    "name" : "Black Forest Cake 2kg",
    "price" : "3500.0",
    "product_id" : "59",
    "quantity" : "1",
    "reader_id" : "93",
    "uid" : ""
  }}

Upvotes: 0

Views: 443

Answers (1)

Jahson kyalo
Jahson kyalo

Reputation: 301

You need to loop this section of your code as below. Hope this helps you.

 Map < String, Object > newPost =
   (Map < String, Object > ) dataSnapshot.getValue();
 for (Object posts: newPost.values()) {
   Map < String, Object > postMap = (Map < String, Object > ) posts;
   model = new SaleModel(postMap.get("name").toString(),
     postMap.get("attendant_name").toString(),
     postMap.get("created_at").toString());
   String key = dataSnapshot.getKey();

   // Insert into the correct location, based on previousChildName
   if (previousChildName == null) {
     mModels.add(0, model);
     mKeys.add(0, key);

   } else {
     int previousIndex = mKeys.indexOf(previousChildName);
     int nextIndex = previousIndex + 1;
     if (nextIndex == mModels.size()) {
       mModels.add(model);
       mKeys.add(key);

     } else {
       mModels.add(nextIndex, model);
       mKeys.add(nextIndex, key);
       //showNotification(model);
     }
   }
 }

Upvotes: 1

Related Questions