从 Firebase 获取数据以执行拉取刷新和加载更多功能

Posted

技术标签:

【中文标题】从 Firebase 获取数据以执行拉取刷新和加载更多功能【英文标题】:Get the data from the Firebase in limit to perform pull to refresh and load more functionality 【发布时间】:2017-07-19 00:38:50 【问题描述】:

但现在我一次从FireBase 获取所有数据。我想做的是一次获取 LIMITS 中的数据,例如 15 条记录.就像第一次用户从 Firebase 获取 15 条记录一样,当用户在屏幕底部/顶部加载更多数据时,应该有更多的记录来自 Firebase 并添加到列表的底部/顶部。 我已经实现了从Firebase 获取数据库顶部或底部的 15 条记录的逻辑,如下所示:-

public class ChatActivity extends AppCompatActivity implements FirebaseAuth.AuthStateListener 

    private FirebaseAuth mAuth;
    private DatabaseReference mChatRef;

    private Query postQuery;
    private String newestPostId;
    private String oldestPostId;
    private int startAt = 0;
    private SwipeRefreshLayout swipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        mAuth = FirebaseAuth.getInstance();
        mAuth.addAuthStateListener(this);

        mChatRef = FirebaseDatabase.getInstance().getReference();
        mChatRef = mChatRef.child("chats");

         /////GETTING THE VIEW ID OF SWIPE LAYOUT
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);

    /////GETTING FIRST 10 RECORDS FROM THE FIREBASE HERE
        mChatRef.limitToFirst(10).addListenerForSingleValueEvent(new ValueEventListener() 
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) 
                for (DataSnapshot child : dataSnapshot.getChildren()) 
                    oldestPostId = child.getKey();
                    System.out.println("here si the data==>>" + child.getKey());
                      
            

            @Override
            public void onCancelled(DatabaseError databaseError) 

            
        );

        //////FOR THE PULL TO REFRESH CODE IS HERE
       swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() 
            @Override
            public void onRefresh() 
                // Refresh items  

             System.out.println("Here==>>> "+oldestPostId);

                ///HERE "oldestPostId" IS THE KEY WHICH I GET THE LAST RECORDS FROM THE FIREBASE

                mChatRef.startAt(oldestPostId).addListenerForSingleValueEvent(new ValueEventListener() 
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) 
                for (DataSnapshot child : dataSnapshot.getChildren()) 

                    System.out.println("here AFTER data added==>>" + child.getKey());
                
            

            @Override
            public void onCancelled(DatabaseError databaseError) 

            
        );

            
        );
    

我已经在这里搜索过它,但没有得到预期的结果,下面是我搜索过的链接 1.First Link 2.Second Link 3.Third Link 4.Forth Link

请在图片中查看我的 Firebase 数据结构。

我已经实现了第一次获取 15 或 10 条记录的逻辑并且它有效..并且还实现了在限制中加载更多记录的逻辑,但是 没有得到正确的解决方案(不工作),请帮忙,让我知道我在哪里做错了..谢谢:)

编辑解决方案

:- 我已经在此链接上实现了加载更多或拉动刷新功能:- Firebase infinite scroll list view Load 10 items on Scrolling

【问题讨论】:

github.com/milon87/ShakeTopUp/tree/master/app/src/main/java/xyz/… 你可以检查一下。不过,这已由 MVP 实现。只需检查 ModelOfferImpl.java 文件。希望它会有所帮助。 参考这个以获得这个问题的完整解决方案:- ***.com/a/44796538/3946958 @RavindraKushwaha 你有没有机会用swift写一个完整的答案,我的意思是把你的整个代码解决方案放在swift中?谢谢 @bibscy 对不起,我只在安卓上工作。我会请我的朋友帮助你。你可以在这里发个问题。。肯定有人帮助你 @RavindraKushwaha 你能请你的朋友看看我的问题吗? ***.com/questions/51975438 【参考方案1】:

您缺少orderByKey()。对于任何过滤查询,您必须使用排序函数。参考documentation

在您的onRefresh 方法中,您需要设置限制:

 public void onRefresh() 
     // Refresh items  
     ///HERE "oldestPostId" IS THE KEY WHICH I GET THE LAST RECORDS FROM THE FIREBASE
                mChatRef.orderByKey().startAt(oldestPostId).limitToFirst(10).addListenerForSingleValueEvent(new ValueEventListener() 
.....

因此,您检索到的数据是您获得前 10 条记录后仅有的 10 条新记录。

确保保存新检索数据中最旧的键,以便下次刷新时仅检索来自该键的新数据。

建议:不用添加子值侦听器来查找最后一个键,您可以只使用值侦听器并获取具有大小的最后一个数据快照以获取最后一条记录的键。

【讨论】:

你能举例说明你的建议吗?另外,由于某种原因,我使用的和你类似,但我得到了:java.lang.IllegalArgumentException: You must use startAt(String value), endAt(String value) or equalTo(String value) in combination with orderByKey(). Other type of values or using the version with 2 parameters is not supported我的代码是photoRerence.orderByKey().startAt(oldestPostId).limitToFirst(6).addListenerForSingleValueEvent(new ValueEventListener() @TalC 它应该可以工作。您的错误与我在回答中首先提到的相同。您确定您在分享的同一行中遇到错误吗,因为我觉得这很好。 我在该行收到错误。我认为这可能是由于在调用特定密钥之前没有及时加载。这是因为我使用了一个不同的库,该库目前在我的应用程序中存在问题。所以我初始化了库,然后它立即尝试从 Firebase 请求更多信息,这就是我假设它崩溃的原因。如果我手动输入密钥,它确实有效。所以看来我必须修复一个错误才能修复这个错误。希望这行得通。不过谢谢!修复一个错误,再获得 99 个大声笑。 @kirtan403 指定 .startAt(oldestPostId) 时,结果中是否也包含“oldestPostId”值?如果是,有什么方法可以告诉 firebase 类似 startAfter(oldestPostId) 吗? @SandipSoni 是的,它包括结果。我不这么认为,像 startAfter 这样的东西存在。但是您可以要求 startAt 并删除第一个结果。【参考方案2】:

重组您的数据库,设置一个新的子 ID,它是增量的,例如 0,1,2,3... 等

"chats": 
"-KZLKDF": 
  "id": 0,
  "message": "Hi",
  "name":"username"
,

然后做一个查询方法

public void loadFromFirebase(int startValue,int endValue)

mChatRef.orderByChild(id).startAt(startValue).endAt(endValue).addListenerForSingleValueEvent(this);

确保您已实现 addListenerForSingleValueEvent 然后执行适配器相关任务。 最初从 onCreate 方法调用:

loadFromFirebase(0,10);

注意:在列表中加载新内容时必须注意适配器。

【讨论】:

感谢您的回答.. +1 您的努力.. @kirtan403 解决了我的问题..感谢您的意见

以上是关于从 Firebase 获取数据以执行拉取刷新和加载更多功能的主要内容,如果未能解决你的问题,请参考以下文章

如何初始加载 UITableView 然后观察 Firebase 节点以更改在 Swift 中刷新 tableview?

从 firebase 获取数据后刷新选择器项目

以编程方式获取/刷新 Health Kit 数据?

以编程方式获取/刷新 Health Kit 数据?

如何从 Firebase 获取 PWA 数据

是否可以从 Firebase 同步加载数据?