Android-与听众的Firestore无限分页

时间:2019-03-27 19:01:11

标签: java android firebase google-cloud-firestore

我正在使用Firebase Firestore数据库制作android聊天应用程序,我需要与侦听器进行无限分页以进行数据更改(新消息,删除消息...)

我发现用kotlin写的博客文章以及corse搜索过的firebase文档,并得到以下代码:

SELECT 
    TRY_CONVERT(XML, p.query_plan) AS QueryPlan
FROM sys.dm_exec_cached_plans ps
OUTER APPLY sys.dm_exec_text_query_plan(ps.plan_handle, 0, -1) p

现在,代码假设为第一个20条消息和新消息保存侦听器,第二个为20-40个消息保存侦听器,依此类推,但是由于某种原因,它无法正常工作。我想念什么吗?

问题在于那条线 // firstTime variable shows if function is called from pagination or initially private void addMessagesEventListener(boolean firstTime) { // get collection CollectionReference messagesCollection = chatsCollection.document(chat.getId()).collection(Constants.FIREBASE_MESSAGES_PATH); // create query Query query = messagesCollection.orderBy("timestamp", Query.Direction.DESCENDING); // if NOT first time add startAt if (!firstTime) { query.startAt(startTimestamp); } //limit to 20 messages query.limit(20).get().addOnSuccessListener(queryDocumentSnapshots -> { if (!firstTime) { endTimestamp = startTimestamp; } startTimestamp = (long) queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1).get("timestamp"); Query innerQuery = messagesCollection.orderBy("timestamp").startAt(startTimestamp); if(!firstTime) { innerQuery.endBefore(endTimestamp); } ListenerRegistration listener = innerQuery .addSnapshotListener((queryDocumentSnapshots1, e) -> { if (e != null) { Log.w(TAG, "listen:error", e); return; } for (DocumentChange dc : queryDocumentSnapshots1.getDocumentChanges()) { Message message = dc.getDocument().toObject(Message.class); switch (dc.getType()) { case ADDED: // add new message to list messageListAdapter.addMessage(message); if (firstTime) { messagesList.smoothScrollToPosition(0); } break; case REMOVED: // remove message from list messageListAdapter.removeMessage(message); break; } } }); listeners.add(listener); }); } 总是得到相同的结果。我什至尝试使用documentSnapshot代替时间戳,结果相同。

谢谢。

2 个答案:

答案 0 :(得分:1)

尝试

 @Override
 public void onStart() {
        super.onStart();

        loadFirstQuery();
 }


    public void loadFirstQuery() {


        if (firebaseAuth.getCurrentUser() != null) {

            contentListDashboard.clear();

            String currentUserId = firebaseAuth.getCurrentUser().getUid();              

            // what we do when recycler reach bottom
            recyclerProfileDashboard.addOnScrollListener(new RecyclerView.OnScrollListener() {
               @Override
               public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                   super.onScrolled(recyclerView, dx, dy);

                   // horizontal
                   //Boolean reachBottom = !recyclerView.canScrollHorizontally(-1);

                   // for vertical recycler
                   Boolean reachBottom = !recyclerView.canScrollVertically(-1);


                   if (reachBottom) {
                       loadMorePost(); // do load more post
                   }
               }
           });

            // RETRIEVING FIRST Query
            Query firstQuery = firebaseFirestore
                    .collection("ProfileDashboard")
                    .document(currentUserId)
                    .collection("ProfileInfo")
                    .orderBy("timestamp", Query.Direction.DESCENDING)
                    .limit(20);    

            firstQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                    if (!documentSnapshots.isEmpty()) {
                        // please add if doc not empty
                        if (isFirstPageFirstLoad) {
                            lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1); // array 0, 1, 2
                        }

                        for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {

                            if (doc.getType() == DocumentChange.Type.ADDED) {

                                //String postId = doc.getDocument().getId();
                                contentProfileDashboard = doc.getDocument().toObject(ContentProfileDashboard.class);   


                                // if first page firest load true
                                if (isFirstPageFirstLoad) {
                                    contentListDashboard.add(contentProfileDashboard);
                                } else {
                                    contentListDashboard.add(0, contentProfileDashboard);
                                }


                                // fire the event
                                adapterProfileDashboard.notifyDataSetChanged();
                            }
                        }

                        isFirstPageFirstLoad = false;
                    }
                }
            });
        }
    }

   // Method to load more post
   public void loadMorePost() {

        if (firebaseAuth.getCurrentUser() != null) {

            String currentUserId = firebaseAuth.getCurrentUser().getUid();

            Query nextQuery = firebaseFirestore
                    .collection("ProfileDashboard")
                    .document(currentUserId)
                    .collection("ProfileInfo")
                    .orderBy("timestamp", Query.Direction.DESCENDING)
                    .startAfter(lastVisible)
                    .limit(20);

            nextQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                    if (!documentSnapshots.isEmpty()) {

                        lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
                        for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {

                            if (doc.getType() == DocumentChange.Type.ADDED) {

                                //String postId = doc.getDocument().getId();
                                // contentSeen = doc.getDocument().toObject(ContentProfile.class);
                                // contentList.add(contentSeen);

                                contentProfileDashboard = doc.getDocument().toObject(ContentProfileDashboard.class);
                                contentListDashboard.add(contentProfileDashboard);

                                //adapterSeen.notifyDataSetChanged();
                                adapterProfileDashboard.notifyDataSetChanged();

                            }
                        }
                    }
                }
            });
        }
   }

有什么问题吗?

答案 1 :(得分:1)

我发现了错误。 工作代码为:

private void addMessagesEventListener(boolean firstTime) {
    CollectionReference messagesCollection = chatsCollection.document(chat.getId()).collection(Constants.FIREBASE_MESSAGES_PATH);
    Query query = messagesCollection.orderBy("timestamp", Query.Direction.DESCENDING);
    if (!firstTime) {
        query = query.startAt(startListen);
    }
    query.limit(20).get().addOnSuccessListener(queryDocumentSnapshots -> {
        if (!firstTime) {
            endListen = startListen;
        }
        startListen = queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1);

        Query innerQuery = messagesCollection.orderBy("timestamp").startAt(startListen);
        if(!firstTime) {
            innerQuery = innerQuery.endBefore(endListen);
        }
        ListenerRegistration listener = innerQuery
                .addSnapshotListener((queryDocumentSnapshots1, e) -> {
                    if (e != null) {
                        Log.w("SASA", "listen:error", e);
                        return;
                    }

                    for (DocumentChange dc : queryDocumentSnapshots1.getDocumentChanges()) {
                        Message message = dc.getDocument().toObject(Message.class);
                        switch (dc.getType()) {
                            case ADDED:
                                // add new message to list
                                messageListAdapter.addMessage(message);
                                if (firstTime) {
                                    messagesList.smoothScrollToPosition(0);
                                }
                                break;
                            case REMOVED:
                                // remove message from list
                                messageListAdapter.removeMessage(message);
                                break;
                        }
                    }
                });
        listeners.add(listener);
    });
}

错误出在query = query.startAt(startListen)innerQuery = innerQuery.endBefore(endListen)

  • startListen和endListen属于DocumentSnapshot类型
  • 我在适配器中使用了sortedList

您应该添加

private void detachListeners() {
    for(ListenerRegistration registration : listeners) {
        registration.remove();
    }
}

在onDestroy中分离所有侦听器。

代码正在侦听添加和删除旧消息。