Firestore Pagination - PullRequest
       5

Firestore Pagination

0 голосов
/ 16 мая 2018

У меня есть вопрос о том, как правильно разбить на страницы запросы с помощью Firestore.

Поместив следующий запрос в OnSuccessListener предыдущего запроса, как в примере на странице Firestore, разве это не неизбежно всегда вызовет цепную реакцию, которая загружает все страницы одновременно? Разве это не то, чего мы хотим избежать с нумерацией страниц?

// Construct query for first 25 cities, ordered by population
Query first = db.collection("cities")
        .orderBy("population")
        .limit(25);

first.get()
    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot documentSnapshots) {
            // ...

            // Get the last visible document
            DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
                    .get(documentSnapshots.size() -1);

            // Construct a new query starting at this document,
            // get the next 25 cities.
            Query next = db.collection("cities")
                    .orderBy("population")
                    .startAfter(lastVisible)
                    .limit(25);

            // Use the query for pagination
            // ...
        }
    });

Источник: https://firebase.google.com/docs/firestore/query-data/query-cursors

Это мой подход. Я знаю, что в реальном приложении я должен использовать RecyclerView, но я просто хочу проверить его на TextView. Я хочу загрузить 3 документа с каждым нажатием кнопки. Имеет ли смысл сохранить lastResult как член, а затем проверить, не является ли он нулевым, чтобы узнать, является ли это первым запросом?

public void loadMore(View v) {
    Query query;
    if (lastResult == null) {
        query = notebookRef.orderBy("priority")
                .orderBy("title")
                .limit(3);
    } else {
        query = notebookRef.orderBy("priority")
                .orderBy("title")
                .startAfter(lastResult)
                .limit(3);
    }
    query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            String data = "";

            for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                Note note = documentSnapshot.toObject(Note.class);
                note.setDocumentId(documentSnapshot.getId());

                String documentId = note.getDocumentId();
                String title = note.getTitle();
                String description = note.getDescription();
                int priority = note.getPriority();

                data += "ID: " + documentId
                        + "\nTitle: " + title + "\nDescription: " + description
                        + "\nPriority: " + priority + "\n\n";
            }

            if (queryDocumentSnapshots.size() > 0) {
                data += "_____________\n\n";
                textViewData.append(data);


                lastResult = queryDocumentSnapshots.getDocuments()
                        .get(queryDocumentSnapshots.size() - 1);
            }
        }
    });
}

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Построение запроса еще не считывает данные из этого запроса.

Таким образом, этот код просто создает запрос:

Query next = db.collection("cities")
        .orderBy("population")
        .startAfter(lastVisible)
        .limit(25);

Он не читает никаких данных из базы данных. Это означает, что он также не использует метод onSuccess.

Если вы сразу же next.get().addOnSuccessListener(..., вы действительно создадите цикл, который загружает всю страницу.

0 голосов
/ 16 мая 2018

Вы должны использовать ScrollListener в вашем обзоре / просмотре списков.при запуске вы получаете 25 пределов данных, как только пользователь снова прокручивает страницу до конца, вы должны сделать новый вызов Firestore с ограничением (что бы вы ни сохраняли).но в это время вы должны продолжать использовать startAt() в своем запросе.ввод в startAt() будет вашим последним ключом из первых полученных данных. Это просто базовый обзор.Вы можете ссылаться на эту ссылку для запроса.

Вы можете создать нумерацию страниц в обзоре / просмотре списка утилит с помощью firestore следующим образом:

В основном выполните следующие действия:

1) При открытии Activity / Fragment ваш первый запрос получит 25 пределов данных

Query first = db.collection("cities")
        .orderBy("population")
        .limit(25);

first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot documentSnapshots) {
            // add data to recyclerView/listview

            // Get the last visible document
            DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
                    .get(documentSnapshots.size() -1);
        }
    });

2) Теперь перезаписать onScrollListener адаптера

boolean isEndChildResults = false;
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                        isScrolling = true;
                    }
                }
   @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            currentVisibleItem = linearLayoutManager.getChildCount();
            totalItem = linearLayoutManager.getItemCount();
            scrolledItem = linearLayoutManager.findFirstVisibleItemPosition();
            if (isScrolling && (currentVisibleItem + scrolledItem == totalItem) && !isEndChildResults && documentSnapshot != null) {
                isScrolling = false;
                mProgressBarScroll.setVisibility(View.VISIBLE);

                FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();

                Query query = firebaseFirestore.collection(...).document(...).limit(25).orderBy(...).startAt(lastVisible);
                query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {

                        if (task.isSuccessful()) {
                          // add data to recyclerView/listview
                          lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() -1);


                     if (task.getResult().size() < postPerPageLimit) {
                       // if your result size is less than your query size which means all the result has been displayed and there is no any other data to display 
                                    isEndChildResults = true;
                                }
                            }

                        }
                    }
                });

          if(isEndChildResults){
         // show snackbar/toast
            }
         }

* lastVisible documentSnapshot будетизменяться при каждой прокрутке, и он будет извлекать данные из lastVisible снимок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...