如何将永久监听器附加到Firestore查询?

huangapple go评论63阅读模式
英文:

How to attach a permanent listener to a Firestore query?

问题

我正在尝试在Firestore中实现分页。我已经创建了一个类似这样的EventListener对象:

EventListener<QuerySnapshot> listener = (querySnapshot, e) -> {
    if (e != null) return;

    for (DocumentChange documentChange : querySnapshot.getDocumentChanges()) {
        //获取数据
    }
    lastVisible = querySnapshot.getDocuments().get(querySnapshot.size() - 1);
};

我还有一个类似这样的查询:

Query query = usersRef.orderBy("name", ASCENDING).limit(4);

在我的onCreate中,我这样做:

query.addSnapshotListener(MainActivity.this, listener);

为了在我的RecyclerView中实现分页,我使用了以下代码:

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {}

    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        query = query.startAfter(lastVisible);
        query.addSnapshotListener(MainActivity.this, listener);
    }
};
recyclerView.addOnScrollListener(onScrollListener);

这意味着当用户达到限制时,我想加载下一个用户。然而,我没有获得正确的索引。根据Frank van Puffelen的回答,我正在使用多个监听器,这确实是我正在做的,因为我两次使用了query.addSnapshotListener()。我的问题是,如何在不附加新监听器的情况下替换第一个查询为第二个查询?如何始终使用同一个监听器?

英文:

I'm trying to implement pagination in Firestore. I have created an EventListener object like so:

EventListener&lt;QuerySnapshot&gt; listener = (querySnapshot, e) -&gt; {
    if (e != null) return;

    for (DocumentChange documentChange : querySnapshot.getDocumentChanges()) {
        //Get data
    }
    lastVisible = querySnapshot.getDocuments().get(querySnapshot.size() - 1);
};

I also have a Query like so:

Query query = usersRef.orderBy(&quot;name&quot;, ASCENDING).limit(4);

In my onCreate I do this:

query.addSnapshotListener(MainActivity.this, listener);

To implement pagination in my RecyclerView, I use:

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {}

    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        query = query.startAfter(lastVisible);
        query.addSnapshotListener(MainActivity.this, listener);
    }
};
recyclerView.addOnScrollListener(onScrollListener);

Meaning that when the user reaches the limit, I want to load next users. However, I don't get the right indexes. According to Frank van Puffelen's answer, I'm using multiple listeners, which is indeed what I'm doing, since I'm using query.addSnapshotListener() twice. My question is, how to replace the first query, with the second one without attaching a new listener? How to always use the same listener?

答案1

得分: 2

不能简单地替换监听器的查询。当您将监听器添加到查询时,它将永远使用该查询,直到将监听器移除。

如果您想要开始获取新查询的结果,您将不得不重复这个过程,并将监听器添加到那个新查询。如果您希望,您可以使用相同的监听器对象,但是您不能简单地“切换到”一个新查询。

英文:

It's not possible to simply replace the query for a listener. When you add a listener to a query, it will forever use that query until the listener is removed.

If you want to start getting results for a new query, you will have to repeat the process and add a listener to that new query. You can use the same listener object if you want, but you can't simply "swap in" a new query.

答案2

得分: 0

关于分页的建议是在远程数据和应用程序之间使用本地数据库作为中间层。思路是将数据存入数据库,这样你就可以完全控制数据的分页。例如,当你需要数据时,从数据库查询;如果查询不存在,再从 Firebase 查询,并将数据缓存到数据库,以供后续请求使用。这就是流程。如果你不理解,可以问我。

附注:这只是一个建议,不是针对你问题的解决方案。

英文:

My advice to pagination is using local database as the layer between your remote data and your app. The idea is, get the data into your database, which you can have absolute control in paginating the data. For example, when you need the data, query your database, if the query doesn't exists, query your firebase, cache the data to your database which will in turn feed your request.
That is the flow. If you don't understand you can ask me.

PS: this is just an advice, not an answer to your problem.

huangapple
  • 本文由 发表于 2020年7月24日 16:41:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63070004.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定