使用Firebase Realtime Database是否需要分页?如何修改代码实现分页?
Firebase Realtime Database分页问题解答
是否需要分页
是,必须做分页处理,原因如下:
- 若
Campsite节点下数据量超过百条,一次性拉取会消耗过多用户流量,延长加载等待时间 - Firebase Realtime Database对单次查询返回的数据量有隐性限制,数据量过大时会出现返回内容截断、请求超时的问题
- 全量加载会导致列表渲染卡顿,交互体验极差
你之前的limit方法不生效的原因
startAt()和limitToFirst()必须传入有效值,空参调用不会产生任何过滤效果- 你原有业务是按
country字段过滤数据,直接改为orderByKey()会打乱原有过滤逻辑,分页和过滤规则不匹配 - Realtime Database单次查询仅支持一个排序规则,你需要将过滤逻辑和分页逻辑合并到同个查询规则中
现有代码修改方案
首先先定义全局分页相关变量:
// 每页加载数量,可根据业务调整 private static final int PAGE_SIZE = 15; // 记录上一页最后一条数据的节点key,作为分页游标 private String mLastKey = null; // 加载锁,避免重复触发分页请求 private boolean mIsLoading = false;
然后修改数据加载逻辑,封装为通用的加载方法支持首次加载和分页加载:
private void loadCampsiteData(boolean isLoadMore) { if (mIsLoading) return; mIsLoading = true; if (!isLoadMore) { // 首次加载清空列表 camperSiteModel.clear(); mLastKey = null; } Query query; DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Campsite"); if (mLastKey == null) { // 加载第一页 query = reference.orderByChild("country").equalTo(country).limitToFirst(PAGE_SIZE); } else { // 加载下一页,使用双参数startAt,第一个参数为过滤字段值,第二个为上一页最后一条的key query = reference.orderByChild("country").startAt(country, mLastKey).limitToFirst(PAGE_SIZE + 1); } query.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { progressDialog.dismiss(); if(seatch_bar.getText().toString().equals("")){ int count = 0; for(DataSnapshot snapshot : dataSnapshot.getChildren()){ // 跳过和上一页重复的最后一条数据 if (count == 0 && mLastKey != null && snapshot.getKey().equals(mLastKey)) { count++; continue; } // 最多只加PAGE_SIZE条,多取的1条是下一页的游标 if (count >= PAGE_SIZE) break; CamperSiteModel camperSiteModel1 = snapshot.getValue(CamperSiteModel.class); camperSiteModel.add(camperSiteModel1); // 更新最后一条key mLastKey = snapshot.getKey(); count++; } camperSiteAdapter.notifyDataSetChanged(); } mIsLoading = false; } @Override public void onCancelled(@NonNull DatabaseError error) { mIsLoading = false; progressDialog.dismiss(); // 按需添加错误处理逻辑 } }); }
后续给列表添加滚动监听,当列表滚动到底部时调用loadCampsiteData(true)即可触发下一页加载。
内容的提问来源于stack exchange,提问作者user16489264
相关产品推荐
相关产品推荐

