0

Here is my Firebase structure

Firebase JSON

I'm trying to select all the IDs with the same date and populate a recycler view with it, here is my code snippet:

 private void updateValues()
    {
        if(rAuth !=null && rUser!=null)
        {
            final String date="15/03/2018";
            final DatabaseReference rRef =
                    FirebaseDatabase.getInstance().getReference()
                    .child("Users")
                    .child("Transactions");

            rRef.child("Expense").addValueEventListener(new ValueEventListener()
            {
                @Override
                public void onDataChange(DataSnapshot rSnap)
                {
                    for(DataSnapshot d: rSnap.getChildren())
                    {
                        rRef.child(d.getKey())
                                .child("Date")
                                .addListenerForSingleValueEvent(new ValueEventListener()
                                {
                                    @Override
                                    public void onDataChange(DataSnapshot dataSnapshot)
                                    {
                                        if(date.equals(dataSnapshot.getValue().toString()))
                                        {
                                            recordItems.add(new recordItems(iconGetter(d.child("Type").getValue().toString()),
                                                    d.child("Description").getValue().toString(),
                                                    d.child("Type").getValue().toString(),
                                                    d.child("Value").getValue().toString(),
                                                    d.child("Date").getValue().toString()));
                                        }
                                    }

                                    @Override
                                    public void onCancelled(DatabaseError databaseError)
                                    {

                                    }
                                });
                    }
                    initRecycler();
                }

                @Override
                public void onCancelled(DatabaseError databaseError)
                {

                }
            });

now since i'm trying to access DataSnapshot d from an inner class I need to make it final, but if I do that, I can't iterate it anymore. I am a bit stuck here since it's my first time using Firebase. I have only used SQL in the past.

recordItems is my model(is that what it's called?) class for storing and providing values to the recycler adapter

Is there a better way to do this? I need to sort these by date, I thought about restructuring the database but I would prefer if there was another way.

Forgive my messy code, I intend to fix it once I get it working. Thanks for any help in advance.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Manan Adhvaryu
  • 323
  • 3
  • 14

2 Answers2

2

First of all you should fix those code line and add the User-id:

 final DatabaseReference rRef =
                FirebaseDatabase.getInstance().getReference()
                .child("Users")
                .child("Transactions");

Should look like that:

 final DatabaseReference rRef =
                FirebaseDatabase.getInstance().getReference()
                .child("Users")
                .child(userId)
                .child("Transactions");

Now, if you want to make your code more efficient you can get only the desired dates with the next query:

 final Query refQuery =
                FirebaseDatabase.getInstance().getReference()
                .child("Users")
                .child(userId)
                .child("Transactions")
                .child("Expense")
                .orderByChild("Date").equalTo(date);

Then, you don't even need to call the addListenerForSingleValueEvent method, because Firebase Realtime-Database always retrieve all the children of the specified Reference.

So all you need is to add your Code line inside the foreach loop:

for (DataSnapshot d : dataSnapshot.getChildren()){ 
     recordItems.add(new recordItems(iconGetter(d.child("Type").getValue().toString()),
           d.child("Description").getValue().toString(),
           d.child("Type").getValue().toString(),
           d.child("Value").getValue().toString(),
           d.child("Date").getValue().toString()));
}

And don't forget to notify yout adapter after adding all the new items to the list with adapter.notifyDataSetChanged() and of course after you called initRecycler(); in the beginning of this whole code.

Hope I helped! You are welcome to check my solution and tell if there are any problems

yotam ravits
  • 181
  • 10
1

If you wanna retrieve all those Expense childs based on the given date

You need to declare your given date value as Global .

I would recommend you to use addChildEventListener and override all the methods.

Then, You have to create a pojo class for getting all those values in the form of an object.

Give this a try :

First create a class with the name :

ExpenseModel.java

paste this on it .

public class ExpenseModel {

    String Date,Description,Type,Value;

    public  ExpenseModel(){

    }


    public ExpenseModel(String date, String description, String type, String value) {


        Date = date;
        Description = description;
        Type = type;
        Value = value;
    }




    public String getDate() {


        return Date;
    }

    public void setDate(String date) {


        Date = date;
    }

    public String getDescription() {


        return Description;
    }

    public void setDescription(String description) {


        Description = description;
    }

    public String getType() {


        return Type;
    }

    public void setType(String type) {


        Type = type;
    }

    public String getValue() {


        return Value;
    }

    public void setValue(String value) {


        Value = value;
    }
}

And The method should be something like this

final String date="15/03/2018";

private void updateValues()
{
    if(rAuth !=null && rUser!=null)
    {
        final DatabaseReference rRef =
                FirebaseDatabase.getInstance().getReference()
                        .child("Users")
                        .child("Transactions");

        rRef.child("Expense").addChildEventListener(new ChildEventListener() {









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


                ExpenseModel expenseModel =  dataSnapshot.getValue(ExpenseModel.class);



                assert expenseModel != null;
                if(expenseModel.getDate().equals(date)){


                    // Add it to the recyclerView
                    // And call notifyDataSetChanged()

                    yourAdapter.add(expenseModel);
                    yourAdapter.notifyDataSetChanged();


                }
            }

            @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) {


            }
        });

Hope this at least helps till some extent, let me know if you still faced any problem.

Cheers

Niamatullah Bakhshi
  • 1,445
  • 16
  • 27
  • Hey, thanks for the answer, even though the above solution worked this one also seems interesting. I didn't understand this though yourAdapter.add(expenseModel); yourAdapter.notifyDataSetChanged(); am I supposed to replace the recordItems with expenseModel? and is yourAdapter the recyclerviewadapter or something else. sorry if these are all really silly questions. I'm still learning. – Manan Adhvaryu Mar 14 '18 at 23:08
  • happy to hear that buddy, The data comes in the form of `ExpenseModel` from firebase. replace yourAdapter with your own Adapter Class which you have created in order to populate your RecyclerView . and yes the recyclerviewadapter as you said. – Niamatullah Bakhshi Mar 14 '18 at 23:14