从 Firebase 中的嵌套查询填充回收站视图

Posted

技术标签:

【中文标题】从 Firebase 中的嵌套查询填充回收站视图【英文标题】:Populating Recycler View From Nested Queries in Firebase 【发布时间】:2019-08-10 15:18:32 【问题描述】:

我正在尝试使用嵌套查询填充回收站视图。第一个查询转到 groups_list 节点并获取节点中的数据和唯一键。然后它使用该键进入组节点并获取该键下的数据。这两个查询的结果都需要在回收站视图中更新。

简而言之,第一个查询得到一些数据和一个键,该键用于进行第二个查询。这两个查询的结果都需要在回收站视图中更新。我为此使用了模型类和回收器视图适配器。

但我在下面遇到错误。

我的片段如下:

// 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());

        
    );

我的 Firebase 数据库结构看起来像

  "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"
      
    
  ,

模型类是

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;
    

错误是

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

datasnapshots 的日志如下...第一个...

第二个的日志...

可能的解决方案 1(传递给 Recycler 查看问题否则有效)

这似乎是以正确的顺序获取数据,现在只需将其传递到模型数组列表并设置适配器

// 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) 

    
);

可能的解决方案 2(列表合并是一个问题 - 否则有效)

  // 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 你的回答是错误的,请看下面的截图:

工作解决方案基于 Prateek Jains 输入

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;

    

【问题讨论】:

我已经取得了一些进展,但还没有得到最终结果,请参阅***.com/questions/55259345/…' 【参考方案1】:

您必须将所需的数据添加到适配器用于呈现视图的列表中。完成后,您必须调用 notifyDataSetChanged,以便适配器可以从更新的列表中重新加载其数据。

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) 

        
   );

【讨论】:

这是一个构造函数错误,能否请您发布您的 GroupListModel 类? 你的 GroupListModel 接受 10 个参数,你必须将所有这些参数传递给它。

以上是关于从 Firebase 中的嵌套查询填充回收站视图的主要内容,如果未能解决你的问题,请参考以下文章

FireBase 实时数据库:回收站视图未填充

从firebase检索图像以在片段中的回收器视图时出错

片段视图返回后执行的 Firebase 查询

单击 RecyclerView 后使用 Firebase 实时数据库填充详细信息活动

使用 firebase 未显示回收站视图 - kotlin

使用 OnClick 删除回收站视图中的项目。 Firebase 安卓