G. R.
G. R.

Reputation: 41

Android/Firebase - How to add retrieved data to an ArrayList

I'm having some issues trying to do this because the data is loaded async.

I have an recyclerView and I need to push the data into a list so it can be recycled displaying the infos on the screen, but it turns out to be kinda hard to do this.

That's what I got until now:

refQuestions.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                Question question = dataSnapshot.getValue(Question.class);
                arrayList.add(question.title);
                Log.d("MyApp", question.title);
            }

I want the code to kinda "stops" here and only continue to executes after the data has been completely loaded into my array, like some kind of callback.

Upvotes: 2

Views: 995

Answers (3)

Deepak Kumar
Deepak Kumar

Reputation: 677

You can use the onDataChange method to add the fetched result to the arraylist

ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
        Question question = ds.getValue(Question.class);
        arrayList.add(question.title);
    }
}
});

And then you can easily display them in the recycler view. For more info click here

Upvotes: 0

Alex Mamo
Alex Mamo

Reputation: 138824

You can use addChildEventListener or you can use addListenerForSingleValueEvent, as in my code below:

ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> arrayList = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Question question = ds.getValue(Question.class);
            arrayList.add(question.title);
        }

        //Do what you need to do with your arrayList
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage());
    }
};
refQuestions.addListenerForSingleValueEvent(valueEventListener);

As you can see, a quick solve for this problem is to use the arrayList only inside the onDataChange() method. If you want to use it outside, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Upvotes: 1

Anubhab Maji
Anubhab Maji

Reputation: 648

private void getQuestions() {
    DatabaseReference refQuestions = /* initialise the reference here */;
    refQuestions.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                /* keep iterating through all the children, this way you can
                   keep track of the retrieval progress */
                for (DataSnapshot question : dataSnapshot.getChildren()) {
                    arrayList.add(question.getValue(Question.class).title);
                }
                /* this is where you write the code what to do after getting
                   all data or call another function to do the job*/
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

You can also replace this..

refQuestions.addListenerForSingleValueEvent(new ValueEventListener() {

with

refQuestions.addValueEventListener(new ValueEventListener() {

for real-time update

Upvotes: 0

Related Questions