Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating Recycler View From Nested Queries in Firebase

I am trying to populate a recycler view using nested queries. The first query goes to groups_list node and takes data in the node and the unique key. Then it goes to groups node with the key and gets data under that key. The result of both the queries needs to be updated in recycler view.

In short, the first query gets some data and a key, the key is used to make the second query. The result from both these queries need to be updated in the recycler view. I am using a model class and recycler view adapter for this.

But I am getting an error below.

My Fragment is as follows:

// Firebase
    fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
    fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
    fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");

    fbDatabaseRefGroupList.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            // Array to Get Group List
            lGroupsList = new ArrayList<>();

            if (dataSnapshot.exists()) {

                // Clear Array to Get Group List
                lGroupsList.clear();

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

                    // Use The Model To Format Array List and Pass It Into It
                    GroupsListModel g = glSnapshot.getValue(GroupsListModel.class);

                    // Array to Get Group List
                    lGroupsList.add(g);

                    String groupID = String.valueOf(glSnapshot.getKey());

                    fbDatabaseRefGroups.child(groupID).addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                            if (dataSnapshot.exists()) {

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

                                    // Use The Model To Format Array List and Pass It Into It
                                    GroupsListModel g = gSnapshot.getValue(GroupsListModel.class);

                                    // Array to Get Group List
                                    lGroupsList.add(g);

                                }

                            }

                        }

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

                        }
                    });

                }

                aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
                rvGroupList.setAdapter(aGroupList);

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getCode());

        }
    });

And My Firebase Database Structure Looks Like

  "groups" : {
    "-LaPfENd0G4pHlejrcd6" : {
      "group_creation_date" : 1553078221782,
      "group_logo" : "0",
      "group_member_count" : "0",
      "group_name" : "dog lovers",
      "group_tagline" : "we love dogs..."
    },
    "-LaPhG0YHnF3FG0Czxom" : {
      "group_creation_date" : 1553078751686,
      "group_logo" : "0",
      "group_member_count" : "0",
      "group_name" : "hi",
      "group_tagline" : "hello"
    }
  },
  "groups_list" : {
    "F81wvGx9a7fXRrfVPQMhQtkM0wv2" : {
      "-LaPfENd0G4pHlejrcd6" : {
        "block_status" : "0",
        "hide_status" : "0",
        "notification_status" : "0",
        "pin_sequence" : "0",
        "report_status" : "0"
      },
      "-LaPhG0YHnF3FG0Czxom" : {
        "block_status" : "0",
        "hide_status" : "0",
        "notification_status" : "0",
        "pin_sequence" : "0",
        "report_status" : "0"
      }
    }
  },

The Model Class Is

public class GroupsListModel {

    private String block_status;
    private String hide_status;
    private String notification_status;
    private String pin_sequence;
    private String report_status;

    private String group_name;
    private Long group_creation_date;
    private String group_logo;
    private String group_member_count;
    private String group_tagline;

    public GroupsListModel() {
    }

    public GroupsListModel(String block_status, String hide_status, String notification_status, String pin_sequence, String report_status, String group_name, Long group_creation_date, String group_logo, String group_member_count, String group_tagline) {
        this.block_status = block_status;
        this.hide_status = hide_status;
        this.notification_status = notification_status;
        this.pin_sequence = pin_sequence;
        this.report_status = report_status;
        this.group_name = group_name;
        this.group_creation_date = group_creation_date;
        this.group_logo = group_logo;
        this.group_member_count = group_member_count;
        this.group_tagline = group_tagline;
    }

    public String getBlock_status() {
        return block_status;
    }

    public void setBlock_status(String block_status) {
        this.block_status = block_status;
    }

    public String getHide_status() {
        return hide_status;
    }

    public void setHide_status(String hide_status) {
        this.hide_status = hide_status;
    }

    public String getNotification_status() {
        return notification_status;
    }

    public void setNotification_status(String notification_status) {
        this.notification_status = notification_status;
    }

    public String getPin_sequence() {
        return pin_sequence;
    }

    public void setPin_sequence(String pin_sequence) {
        this.pin_sequence = pin_sequence;
    }

    public String getReport_status() {
        return report_status;
    }

    public void setReport_status(String report_status) {
        this.report_status = report_status;
    }

    public String getGroup_name() {
        return group_name;
    }

    public void setGroup_name(String group_name) {
        this.group_name = group_name;
    }

    public Long getGroup_creation_date() {
        return group_creation_date;
    }

    public void setGroup_creation_date(Long group_creation_date) {
        this.group_creation_date = group_creation_date;
    }

    public String getGroup_logo() {
        return group_logo;
    }

    public void setGroup_logo(String group_logo) {
        this.group_logo = group_logo;
    }

    public String getGroup_member_count() {
        return group_member_count;
    }

    public void setGroup_member_count(String group_member_count) {
        this.group_member_count = group_member_count;
    }

    public String getGroup_tagline() {
        return group_tagline;
    }

    public void setGroup_tagline(String group_tagline) {
        this.group_tagline = group_tagline;
    }
}

And The Error is

Can't convert object of type java.lang.Long to type com.example.myproject

The logs from datasnapshots are coming as follows... first one... enter image description here

The log from second one... enter image description here

Possible Solution 1 (Passing To Recycler View An Issue Otherwise Working)

This seems to be getting the data in proper sequence now just have to pass it into the Model Array List and Set The Adapter

// Get The Data
fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        if (dataSnapshot.exists()) {

            final String groupID = dataSnapshot.getKey();

            final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
            final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
            final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
            final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
            final String reportStatus = (String) dataSnapshot.child("report_status").getValue();

            fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                    String groupName = (String) dataSnapshot.child("group_name").getValue();
                    String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
                    String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();


                }

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

                }
            });

        }

    }

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

    }

    @Override
    public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

    }

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

    }

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

    }
});

Possible Solution 2 (List Merging Is An Issue - Otherwise Working)

  // Firebase
    fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
    fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
    fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");

    // Array to Get Group List
    lGroupsListList = new ArrayList<>();
    lGroupsList = new ArrayList<>();
    lCombinedList = new ArrayList<>();

    // Clear Array to Get Group List
    lGroupsList.clear();
    // Clear Array to Get Group List
    lGroupsListList.clear();
    // Clear Array to Get Group List
    lCombinedList.clear();

    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

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

                // Use The Model To Format Array List and Pass It Into It
                GroupsListModel g = ds.getValue(GroupsListModel.class);

                // Array to Get Group List
                lGroupsListList.add(g);

                final String key = ds.getKey();

                final String blockStatus = (String) ds.child("block_status").getValue();

                DatabaseReference keyRef = fbDatabaseRootNode.child("groups").child(key);

                ValueEventListener eventListener = new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {

                        // Use The Model To Format Array List and Pass It Into It
                        GroupsListModel g = dataSnapshot.getValue(GroupsListModel.class);

                        // Array to Get Group List
                        lGroupsList.add(g);

                        String groupName = (String) dataSnapshot.child("group_name").getValue();

                        Log.d(TAG, "groupdetails: " + key + "--" + groupName + "--" + blockStatus);

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
                        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
                    }
                };

                keyRef.addListenerForSingleValueEvent(eventListener);

            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
        }
    };

    aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
    rvGroupList.setAdapter(aGroupList);

    fbDatabaseRefGroupList.addListenerForSingleValueEvent(valueEventListener);

@Prateek Jain Your answer is giving error please see screenshot below: enter image description here

Working Solution Based on Prateek Jains Inputs

public class GroupsListFragment extends Fragment {

    private static final String TAG = "GroupsListFragment";

    // Recycler View
    private RecyclerView rvGroupList;
    private GroupsListAdapter aGroupList;

    private List<GroupsListModel> lGroupsListList;
    private List<GroupsListModel> lGroupsList;
    private List<GroupsListModel> lCombinedList;

    // Firebase
    private FirebaseAuth mAuth;
    private DatabaseReference fbDatabaseRootNode;
    private DatabaseReference fbDatabaseRefGroupList;
    private DatabaseReference fbDatabaseRefGroups;
    private String current_user_id;

    private String groupID;
    private List<String> lgroupIDs;

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

        View view = inflater.inflate(R.layout.fragment_groups_list, container, false);

        mAuth = FirebaseAuth.getInstance();
        current_user_id = mAuth.getCurrentUser().getUid();

        // Init Recycler View
        rvGroupList = view.findViewById(R.id.f_groups_list_groups_list);
        rvGroupList.setHasFixedSize(true);
        rvGroupList.setLayoutManager(new LinearLayoutManager(getActivity()));

        // Firebase
        fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
        fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
        fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");

        // Get The Data
        fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                // Array to Get Group List
                lGroupsList = new ArrayList<>();

                if (dataSnapshot.exists()) {

                    // Clear Array to Get Group List
                    lGroupsList.clear();

                    final String groupID = dataSnapshot.getKey();

                    final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
                    final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
                    final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
                    final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
                    final String reportStatus = (String) dataSnapshot.child("report_status").getValue();

                    fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                            Long groupCreationDate = (Long) dataSnapshot.child("group_creation_date").getValue();
                            String groupLogo = (String) dataSnapshot.child("group_logo").getValue();
                            String groupMemberCount = (String) dataSnapshot.child("group_member_count").getValue();
                            String groupName = (String) dataSnapshot.child("group_name").getValue();
                            String groupTagLine = (String) dataSnapshot.child("group_tagline").getValue();

                            lGroupsList.add(new GroupsListModel(blockStatus, hideStatus, notificationStatus, pinSequence,
                                    reportStatus, groupName, groupCreationDate, groupLogo, groupMemberCount, groupTagLine));

                            aGroupList.notifyDataSetChanged();
                        }

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

                        }
                    });

                    aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
                    rvGroupList.setAdapter(aGroupList);

                }

            }

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

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

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

            }

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

            }
        });

        return view;

    }
}
like image 462
DragonFire Avatar asked Mar 20 '19 01:03

DragonFire


People also ask

What is nested recycler view?

A nested RecyclerView is an implementation of a RecyclerView within a RecyclerView. An example of such a layout can be seen in a variety of apps such as the Play store where the outer (parent) RecyclerView is of Vertical orientation whereas the inner (child) RecyclerViews are of horizontal orientations.

How fetch data from Firebase Android and display in RecyclerView?

Step 1: Open Android Studio and create a new project named “RecyclerView” with an empty activity. Step 2: Connect your Firebase project with your app. Step 3: Add the following dependency in your app/build. gradle file in order to get the FirebaseUI and Firebase Realtime Database support in the app.


1 Answers

You have to add the required data to the list which is being used by your adapter to render the views. Once that is done you must call notifyDataSetChanged, so that adapter can reload its data from the updated list.

fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        String groupName = (String) dataSnapshot.child("group_name").getValue();
        String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
        String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();
        lGroupsList.add(new GroupsListModel(groupName, groupMemberCount, groupTagLine));
        aGroupList.notifyDataSetChanged();
        }

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

        }
   });
like image 62
Prateek Jain Avatar answered Sep 28 '22 06:09

Prateek Jain