user5866501 user5866501 - 6 months ago 303
Android Question

Firebase Android count children/ badge

I try to develop a simple shopping application. There will be a few product categories and I use different activity with ListView for every category. When User choose product category (say items1 ="drinks")- new screen opens and he can add "soda", "cola"... I want to add count badge on every category to show number of products per category.
So, for example for "items" I need to display 5, for "items1" - 2 and for "items10/11" - display 1:

enter image description here

itemsUrl = Constants.FIREBASE_URL + "/users/" + mUserId + "/items1";


// Set up LisView
final ListView listView = (ListView) findViewById(R.id.listView);
final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
listView.setAdapter(adapter);

// Use Firebase to populate the list.
new Firebase(itemsUrl)
.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
adapter.add((String) dataSnapshot.child("title").getValue());


Log.e(dataSnapshot.getKey(), dataSnapshot.getChildrenCount() + "");
}


After running the code I received Key and number of his children:
E-KJI3NOhypAO9FQDOsoK: 1
E-KJLrK2wK86_3EUW6u_l: 1

it's always 1 child for every Key because Key=Product ID and child of the Key - it's title. But I need to count Keys/ Product IDs (products in category "drinks") and not his children...

Answer

Databse Reference

With this Database you have two options:

1)Use Child Added

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();
//You must remember to remove the listener when you finish using it, also to keep track of changes you can use the ChildChange
myRef.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        Log.e(dataSnapshot.getKey(),dataSnapshot.getChildrenCount() + "");
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {

    }

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

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

2)Use the Value listener

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();

//You can use the single or the value.. depending if you want to keep track
thismyRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot snap: dataSnapshot.getChildren()) {
            Log.e(snap.getKey(),snap.getChildrenCount() + "");
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

Here is the output for both cases

enter image description here

If you need to keep constant tracking is best to use the Child events...because otherwise each time anything changes you will receive the entire json over the network, instead of only the portion of information that was changed

If you need a snapshot only once, you better use the singleValue since this way you will receive all the information at the same time