Есть ли способ разбить запросы на страницы путем объединения курсоров запросов с помощью FirestoreRecyclerAdapter?

у меня есть запрос, который выглядит так:

Query first = ref.orderBy("name", Query.Direction.ASCENDING).limit(10);

вот как я отображаю данные в my RecyclerView.

firestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<ModelClass>().setQuery(query, ModelClass.class).build();
myFirestoreRecyclerAdapter = new MyFirestoreRecyclerAdapter(firestoreRecyclerOptions);
recyclerView.setAdapter(myFirestoreRecyclerAdapter);

Я пытаюсь использовать разбиение на страницы, как указано в здесь и я не могу решить.

first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot documentSnapshots) {
        DocumentSnapshot lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
        Query second = ref.orderBy("name", Query.Direction.ASCENDING).startAfter(lastVisible).limit(10);
        //Create a firestoreRecyclerOptions and setting the adapter
    }
});

есть ли способ разбить запросы на страницы, объединив курсоры запросов с помощью FirestoreRecyclerAdapter? Это вообще возможно?

2 ответов


как @FrankvanPuffelen уже ответил в более раннем вопрос вашего, вы не можете достичь этого, потому что в вашем случае вы должны передать 2 разных запроса (first и second) к одному адаптеру, что невозможно с помощью FirestoreRecyclerAdapter. Вы можете использовать первый запрос или второй с одним экземпляром адаптера.

решением было бы создать два разных списка, содержащих результаты каждого запроса и объединить их. Тогда вы можете пройти полученный список к другому адаптеру, скажем ArrayAdapter и затем отобразить результаты в ListView или еще лучше RecyclerView. Проблема в этом случае заключается в том, что вы не сможете использовать функции реального времени, которые FirestoreRecyclerAdapter класс обеспечивает, но этот подход решит вашу проблему.

Edit:

в соответствии с вашим запросом из раздела комментариев, я дам вам пример о том, как разбить запрос на кнопку нажмите в самом простом способ, используя ListView и ArrayAdapter. Вы можете достичь того же самого, используя RecyclerView при прокрутке вниз. Но чтобы все было просто, предположим, что у нас есть ListView и Button и мы хотим загрузить больше элементов в список при каждом нажатии кнопки. Для этого давайте сначала определим представления:

ListView listView = findViewById(R.id.list_view);
Button button = findViewById(R.id.button);

предположим, что у нас есть структура базы данных, которая выглядит так:

Firestore-root
   |
   --- products (collection)
         |
         --- productId (document)
                |
                --- productName: "Product Name"

и класс модели, который выглядит следующим образом:

public class ProductModel {
    private String productName;

    public ProductModel() {}

    public ProductModel(String productName) {this.productName = productName;}

    public String getProductName() {return productName;}

    @Override
    public String toString() { return productName; }
}

теперь давайте определите запрос с ограничением 3.

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference productsRef = rootRef.collection("products");
Query firstQuery = productsRef.orderBy("productName", Query.Direction.ASCENDING).limit(3);

это означает, что при каждом нажатии кнопки мы загрузим еще 3 элемента. А теперь, вот код, который делает магию:

firstQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<ProductModel> list = new ArrayList<>();
            for (DocumentSnapshot document : task.getResult()) {
                ProductModel productModel = document.toObject(ProductModel.class);
                list.add(productModel);
            }
            ArrayAdapter<ProductModel> arrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, list);
            listView.setAdapter(arrayAdapter);
            lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);

            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Query nextQuery = productsRef.orderBy("productName", Query.Direction.ASCENDING).startAfter(lastVisible).limit(3);
                    nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<QuerySnapshot> t) {
                            if (t.isSuccessful()) {
                                for (DocumentSnapshot d : t.getResult()) {
                                    ProductModel productModel = d.toObject(ProductModel.class);
                                    list.add(productModel);
                                }
                                arrayAdapter.notifyDataSetChanged();
                                lastVisible = t.getResult().getDocuments().get(t.getResult().size() - 1);
                            }
                        }
                    });
                }
            });
        }
    }
});

, в котором lastVisible это DocumentSnapshot объект, представляющий последний элемент visibile из запроса. В этом случае каждый третий и объявляется как переменная gloabl:

private DocumentSnapshot lastVisible;

Edit2: здесь у вас также есть решение о том, как вы можно получить данные из базы данных Firestore и отображать их в меньших кусках в RecyclerView когда пользователь прокручивает.


возможный подход-сохранить клавиши push каждого элемента в отдельном узле.

затем извлеките все ключи из этого узла в список массивов или что-то еще ..

затем на основе вашего номера разбиения на страницы извлеките ключи из этого списка массивов и используйте orderByKey Query и startAt и LimitToFirst запросы в сочетании, чтобы сделать алгоритм разбиения на страницы