如何仅检索一次 firebase 数据库值而不监听子值,即使它们已更改

how to retrieve the firebase database values only once without listening to childvalues even though they have changed

我有这种情况,在我的应用程序中,我试图查询 child 节点并将其传递到列表中到 recyclerview 适配器,当我向上滚动回收器视图项目时出现问题,如果有人插入了一个 post,我的 recyclerview 再次进入第一个 post 项目,而且我正在使用带有三个片段的 viewpager,无论我在哪个片段上,如果有的话,我都会回滚到第一个片段已插入 post 如何解决此问题。 我已经按照下面提到的方式实现了这一点。

我的一种想法是,我认为我不会听 child 事件更改,而是查询结果并在稍后填充 recyclerview,而不是听 child 事件,这样一切都显示为是的,我不知道在 firebase 中如何在不实现侦听器的情况下检索值我尝试了 singleValueEventListener 那样的行为仍然是相同的回滚到第一个项目或第一个片段

指导我解决如何摆脱这种行为。

Query query= databasePostsReference.orderByChild("timestamp");

       query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
                for(DataSnapshot snapshot : dataSnapshot.getChildren()){
                    Log.d(TAG, "onDataChange: entered list adding");
                    UserPostPOJO post = 
                    snapshot.getValue(UserPostPOJO.class);
                    listposts.add(0,post);
                }
                if(listposts.isEmpty()){
                    empty.setVisibility(View.VISIBLE);
                    recyclerView.setVisibility(View.GONE);
                }
                else
                {
                    empty.setVisibility(View.GONE);
                    recyclerView.setVisibility(View.VISIBLE);
                    makelist(listposts);
                }


            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        }); 




private void makelist(List<UserPostPOJO> listposts) {
        list = listposts;
        Log.d(TAG,"size is "+ list.size()+"");

        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new 
        LinearLayoutManager(getActivity()));
        CustomRecyclerViewAdapter adapter = new 
        CustomRecyclerViewAdapter(getActivity(), list,"recentfragment");
        recyclerView.setAdapter(adapter);


    }

有一个名为 removeEventListener() 的方法,您可以调用它来删除特定的 event listener。您从数据库中获取数据,然后调用此方法。所以为了使这项工作,请使用以下代码:

databaseReference.removeEventListener(valueEventListener);

其中 databaseReference 是您最初放置侦听器的引用。

更多详情请阅读offcial doc

希望对您有所帮助。

Firebase 有一个 FirebaseRecyclerAdapter,可以设置为 RecyclerView。它需要一个 DatabaseReferenceQuery 对象并处理数据库和视图之间的所有数据同步。

对于数据库引用对象,同样可以添加事件侦听器,也可以使用removeEventListener.

删除它

而不是像这样创建一个匿名对象

    Query query= databasePostsReference.orderByChild("timestamp");

    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
            for(DataSnapshot snapshot : dataSnapshot.getChildren()){
                Log.d(TAG, "onDataChange: entered list adding");
                UserPostPOJO post = 
                snapshot.getValue(UserPostPOJO.class);
                listposts.add(0,post);
            }
            if(listposts.isEmpty()){
                empty.setVisibility(View.VISIBLE);
                recyclerView.setVisibility(View.GONE);
            }
            else
            {
                empty.setVisibility(View.GONE);
                recyclerView.setVisibility(View.VISIBLE);
                makelist(listposts);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    }); 

您可以创建 ValueEventListener 的命名对象,并在 onDataChange 方法

的末尾使用 removeEventListener 从数据库引用对象中删除它
    Query query= databasePostsReference.orderByChild("timestamp");

    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
            for(DataSnapshot snapshot : dataSnapshot.getChildren()){
                Log.d(TAG, "onDataChange: entered list adding");
                UserPostPOJO post = 
                snapshot.getValue(UserPostPOJO.class);
                listposts.add(0,post);
            }
            if(listposts.isEmpty()){
                empty.setVisibility(View.VISIBLE);
                recyclerView.setVisibility(View.GONE);
            }
            else
            {
                empty.setVisibility(View.GONE);
                recyclerView.setVisibility(View.VISIBLE);
                makelist(listposts);
            }

            query.removeEventListener(valueEventListener);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    }); 

    query.addValueEventListener(valueEventListener);

onDataChange 方法中的代码只执行一次,因为一旦执行方法的最后一行,ValueEventListener 对象就会被删除。