1

I am fetching data from firebase database to a recyclerview. I can't get the data to the RecyclerViewAdapter since the Array list becomes empty after the addListenerForSingleValueEvent method.

@Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
        database = FirebaseDatabase.getInstance();
        ArrayList<Item> arr = new ArrayList<Item>();


        DatabaseReference reference = database.getReference("NoticeBoard");

        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

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

                    String text1 = (String) singleSnapshot.child("Text1").getValue();
                    String text2 = (String) singleSnapshot.child("Text2").getValue();

                    arr.add(new Item(text1, text2));
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });

        RecyclerViewAdapter adapter = new RecyclerViewAdapter(getContext(), arr);// Here the ArrayList arr is empty

        RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(adapter);

        return view;
    }
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
Vishnu
  • 663
  • 3
  • 7
  • 24

2 Answers2

2

onDataChange() is asynchronous therefore since you are calling the arraylist after addListenerForSingleValueEvent, it will return an empty list because the data is not yet retrieved.

To solve your problem, you need to add the arrayList inside onDatachange():

        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

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

                    String text1 = (String) singleSnapshot.child("Text1").getValue();
                    String text2 = (String) singleSnapshot.child("Text2").getValue();
                    ArrayList<Item> arr = new ArrayList<Item>();
                    arr.add(new Item(text1, text2));

                    RecyclerViewAdapter adapter = new RecyclerViewAdapter(getContext(), arr);
                    RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

                    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                    recyclerView.setAdapter(adapter);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
2

Firebase database calls are not asynchronous means the lines below query will be executed before you are getting response from firebase.

So update your code as below to work as expected.

 RecyclerViewAdapter adapter;

 @Override
 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
    database = FirebaseDatabase.getInstance();
    ArrayList<Item> arr = new ArrayList<Item>();

    adapter = new RecyclerViewAdapter(getContext(), arr);// Here the ArrayList arr is empty

    RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setAdapter(adapter);

    DatabaseReference reference = database.getReference("NoticeBoard");

    reference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

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

                String text1 = (String) singleSnapshot.child("Text1").getValue();
                String text2 = (String) singleSnapshot.child("Text2").getValue();

                arr.add(new Item(text1, text2));
            }
            if(adapter != null){
               adapter.notifyDataSetChanged();
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });

    return view;
}

Notes: It is good practice to set data after view has been created in fragments. You can use onViewCreated() method of fragment for that.

DHAVAL A.
  • 2,251
  • 2
  • 12
  • 27