简体   繁体   中英

ArrayList returning null from firebase array adapter

I'm trying to add the data that I got from the datasnapshot into an arraylist but it keeps returning null . I know I should be doing any changes to UI inside of this method however I need to be able to access this outside of the method so I can return the value back to my fragment.

I have added print statements inside the datasnapshot and I can see that I am getting the data I need however outside of the scope of the @Override function it remains empty. I need a way to access this globally to send to my arrayAdapter and return my other activity which implements this fragment. Please help.

public class YourTripTab extends Fragment {

    private DatabaseReference userReference;
    private String userID;
    private String Tag = "YourTripTab";
    private List<Trip> trips = new ArrayList<>();

    public void setUserID(String userID) {
        this.userID = userID;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View tripView = inflater.inflate(R.layout.your_trips, container, false);

        userReference = FirebaseDatabase.getInstance().getReference("userTrips").child(userID);

        //find Id from xml file
        ListView tripListView = (ListView) tripView.findViewById(R.id.trips);

        //create our TripListAdapter array adapter
        TripListAdapter tripListAdapter = new TripListAdapter(getContext(), retrieve());

        tripListView.setAdapter(tripListAdapter);

        return tripView;

    }

    public List<Trip> retrieve() {

        userReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        String startDate = ds.child("startDate").getValue().toString();
                        String tripName = ds.child("tripName").getValue().toString();
                        System.out.println("Trip Name:~ " + ds.getKey() + ":: startDate here ~ " + startDate + "//" + "tripName ~ " + tripName);
                        trips.add(new Trip(tripName, startDate));
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                //no data exists or error getting data
            }

        });

        System.out.println("Here is the size of trips list: " + trips.size());

        return trips;
    }

}

EDIT

I managed to fix it here is the solution

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


        final View tripView = inflater.inflate(R.layout.your_trips, container, false);



        getData(new FirebaseCallback() {
            @Override
            public void onCallBack(List<Trip> list) {
                for(int i = 0; i < list.size(); i++){
                    trips.add(list.get(i));
                }
                tripListView = (ListView) tripView.findViewById(R.id.trips);
                tripListAdapter = new TripListAdapter(getContext(), trips);
                tripListView.setAdapter(tripListAdapter);
            }
        });



        return tripView;

    }


    private interface FirebaseCallback {

        void onCallBack(List<Trip> list);

    }


    private void getData(final FirebaseCallback firebaseCallback) {

        userReference = FirebaseDatabase.getInstance().getReference("userTrips").child(userID);
        userReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    List<Trip> tempList = new ArrayList<>();
                    System.out.println("dataSnapshot is here: " + dataSnapshot);

                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {

                        String startDate = snapshot.child("startDate").getValue().toString();
                        String tripName = snapshot.child("tripName").getValue().toString();
                        System.out.println("startDate here: " + startDate + "\n" + "tripName: " + tripName);
                        tempList.add(new Trip(tripName, startDate));

                    }

                    firebaseCallback.onCallBack(tempList);
                }
            }

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

            }
        });

    }```


addValueEventListener is asynchronous and returns immediately. The callback you passed to it will get invoked some unknown amount of time later, whenever the data is available. This means that your retrieve method also returns immediately with the initial value of trips , which is empty. To state this another way - the first time retrieve is called, it returns an empty List of Trip objects.

If you want your ListView to show data, you should instead set its adapter after you've collected all this trips. This means you should do it inside the addValueEventListener callback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM