【问题标题】:Firebase database pagination in ascending orderFirebase数据库按升序分页
【发布时间】:2018-01-20 12:10:46
【问题描述】:

我在尝试对 firebase 数据库中的数据进行分页数周时遇到了一个很好的问题,但都无济于事。我尝试了从 android 文档到 SO 的所有示例,但仍然无法正常工作。下面是我的数据节点的截图

以下是我的代码,我正在使用 recycleview 进行连续滚动。

commentDatabaseReference = FirebaseDatabase.getInstance().getReference().child(CHANNEL_COMMENT).child(postId);
commentDatabaseReference.orderByKey().limitToLast(TOTAL_ITEM_EACH_LOAD).addListenerForSingleValueEvent(commentValueEventListener);

ValueEventListener commentValueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(!dataSnapshot.hasChildren()) {
                currentPage--;
            }

            int counter = 0;
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                commentId = snapshot.getKey();
                Comment comment = snapshot.getValue(Comment.class);
                commentList.add(comment);

                adapter.notifyDataSetChanged();
            }
            //adapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

Recycleview 持续滚动监听器

recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {

            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                Log.e("more", "onload");
                loadMoreData();
            }
        }); 

private void loadData() {
        Log.e("loading", ""+ commentId);
        commentDatabaseReference.orderByChild("timestamp").startAt(commentId).limitToLast(TOTAL_ITEM_EACH_LOAD)
                .addListenerForSingleValueEvent(commentValueEventListener);
    }

    private void loadMoreData(){
        //if ((currentPage * TOTAL_ITEM_EACH_LOAD) <= commentCount) {
            currentPage++;
            loadData();
        //}
    }

结论:例如,如果我有 20 个偏移量为 10 的数据,并且我使用带有 limitToLast 的 orderby,我会从顶部开始获得最后 10 个数据,即我从 11 - 20 而不是 20 - 11 获得数据。另外注意到有时当我与 startAt 结合时我会得到无休止的数据

【问题讨论】:

    标签: android firebase-realtime-database pagination android-recyclerview


    【解决方案1】:

    使用limitToFirst 并添加一个包含timestamp * -1 的字段(时间戳倒数),例如将其命名为timestampInv

    然后你可以orderByChild("timestampInv")startAt

    commentDatabaseReference
      .orderByChild("timestampInv")
      .startAt(lastTimeInv)
      .limitToFirst(TOTAL_ITEM_EACH_LOAD)
      .addListenerForSingleValueEvent(commentValueEventListener);
    

    如果你想自动创建时间戳倒数,我建议使用cloud functiononCreate 触发器:

    exports.addCommentTimestampInv = functions.database.ref('/comment/{postId}/{commentId}')
    .onCreate(event => {
      // Grab the current value of what was written to the Realtime Database.
      const commentData = event.data.val();
    
      var timeInv = commentData.timestamp * -1;
    
      return event.data.ref.child('timestampInv').set(timeInv);
    
    });
    

    希望对你有帮助:)

    【讨论】:

    • 谢谢@faruk,我会试一试并给你反馈
    • 我尝试了上面的方法,我能够从下面获取数据,但是当我到达顶部时,它会继续不停地提取数据
    【解决方案2】:

    感谢 faruk 的提示,终于解决了这个问题:

    下面的代码方法将数据从firebase加载到recycleview

    private void loadData() {
            Query query;
            if (commentId == null) {
                query = commentDatabaseReference.orderByChild("timestamp").limitToLast(TOTAL_ITEM_EACH_LOAD);
            } else {
                query = commentDatabaseReference.orderByChild("timestamp").startAt(inverseTimestamp).limitToFirst(TOTAL_ITEM_EACH_LOAD);
            }
            query.addListenerForSingleValueEvent(commentValueEventListener);
        }
    
        private void loadMoreData(){
            //commentCount: is the total comments stored in firebase database
            if ((currentPage * TOTAL_ITEM_EACH_LOAD) <= commentCount) {
                currentPage++;
                loadData();
            }
        }
    

    在 recycleview 滚动监听器上,我调用 loadMoreData 方法从 firebase 获取更多数据

    recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
    
                @Override
                public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                    //Load more data
                    loadMoreData();
                }
            });
    

    Firebase 数据库监听器来监听获取的数据

    ValueEventListener commentValueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if(!dataSnapshot.hasChildren()) {
                    currentPage--;
                }
    
                int counter = 0;
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    commentId = snapshot.getKey();//Index key for the node
                    Comment comment = snapshot.getValue(Comment.class);
    
                    ++counter;
    
                    //Inverse timestamp
                    inverseTimestamp = comment.getTimestamp();
    
                    //store nth - 1 data into the arraylist to avoid duplicates
                    if (counter < TOTAL_ITEM_EACH_LOAD) {
                        commentList.add(comment);
    
                        adapter.notifyDataSetChanged();
                    }
                }
                //adapter.notifyDataSetChanged();
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
    
            }
        };
    

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 2018-11-13
      • 2017-08-20
      • 1970-01-01
      • 2019-01-29
      • 2020-07-07
      • 2015-01-27
      • 2021-10-12
      相关资源
      最近更新 更多