Vihaan Verma
Vihaan Verma

Reputation: 13143

Firebase android pagination

I'm building an app which will show videos stored on firebase. The list of videos needs to be paginated fetching most recent 20 videos at a time.

enter image description here

Here is the code I thought would work

  private void getVideos() {

        Query videosQuery = FirebaseUtil.getVideosRef();
        videosQuery.startAt(0);
        videosQuery.endAt(1);

        ChildEventListener videosChildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                String date = dataSnapshot.getKey();
                String temp = date;
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

                Log.d(tag, "database error");
            }
        };


        ValueEventListener videoValueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String date = dataSnapshot.getKey();
                String temp = date;

               long count =  dataSnapshot.getChildrenCount();
                String value = dataSnapshot.getValue().toString();
                temp = value;
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(tag, "database error");
            }
        };
//        videosQuery.addChildEventListener(videosChildEventListener);
        videosQuery.addValueEventListener(videoValueEventListener);

    }

But above code retrieves entire list of videos instead of limited videos. How can pagination be implemented.

Upvotes: 21

Views: 28142

Answers (10)

Dyno Cris
Dyno Cris

Reputation: 2414

If you want to get list from firebase realtime database descending with pagination you need use smth like this:

Query query = myRef.child("stories").orderByChild("takenAt").endAt(1600957136000L).limitToLast(30);

Full code, two requests

        List<Story> storyList = new ArrayList<>();
        
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference();
        
        //first request will be look like this
        Query query = myRef.child("stories").orderByChild("takenAt").endAt(1600957136000L).limitToLast(30);
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        Story story = snapshot.getValue(Story.class);
                        storyList.add(story);
                    }
                }
                Collections.reverse(storyList);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Log.e("ptg", "onCancelled: ", error.toException());
            }
        });
        
        //second request
        long lastTakenAtInTheStoryList = storyList.get(storyList.size()-1).getTakenAt();
        Query query2 = myRef.child("stories").orderByChild("takenAt").endAt(lastTakenAtInTheStoryList).limitToLast(30);
        query2.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        Story story = snapshot.getValue(Story.class);
                        storyList.add(story);
                    }
                }
                Collections.reverse(storyList);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Log.e("ptg", "onCancelled: ", error.toException());
            }
        });

Upvotes: 0

lovish
lovish

Reputation: 49

In the past (but no longer) a question regarding implementing Pagination to a query on Firestore was marked as a duplicate of this question I will answer for FireStore here.

Paginate a query on android Firestore

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

Query next = query;

 private void loadCities() {

     query = next;
     query.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.
                next = db.collection("cities")
                        .orderBy("population")
                        .startAfter(lastVisible)
                        .limit(25);

            }
        });         
 }

Now just call the loadCities() method whenever you need to load more cities.

Upvotes: -1

Shreyas Patil
Shreyas Patil

Reputation: 954

You can achieve it by using Firebase database paging library as below code... In this code, I have shown Post as an data model item and PostViewHolder as ViewHolder

        //Initialize RecyclerView
        mRecyclerView = findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);

        LinearLayoutManager mManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mManager);

        //Initialize Database
        mDatabase = FirebaseDatabase.getInstance().getReference().child("posts");

        //Initialize PagedList Configuration
        PagedList.Config config = new PagedList.Config.Builder()
                .setEnablePlaceholders(false)
                .setPrefetchDistance(5)
                .setPageSize(10)
                .build();

        //Initialize FirebasePagingOptions
        DatabasePagingOptions<Post> options = new DatabasePagingOptions.Builder<Post>()
                .setLifecycleOwner(this)
                .setQuery(mDatabase, config, Post.class)
                .build();

        //Initialize Adapter
        mAdapter = new FirebaseRecyclerPagingAdapter<Post, PostViewHolder>(options) {
            @NonNull
            @Override
            public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                return new PostViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false));
            }

            @Override
            protected void onBindViewHolder(@NonNull PostViewHolder holder,
                                            int position,
                                            @NonNull Post model) {
                holder.setItem(model);
            }

            @Override
            protected void onLoadingStateChanged(@NonNull LoadingState state) {
                switch (state) {
                    case LOADING_INITIAL:
                    case LOADING_MORE:
                        // Do your loading animation
                        mSwipeRefreshLayout.setRefreshing(true);
                        break;

                    case LOADED:
                        // Stop Animation
                        mSwipeRefreshLayout.setRefreshing(false);
                        break;

                    case FINISHED:
                        //Reached end of Data set
                        mSwipeRefreshLayout.setRefreshing(false);
                        break;

                    case ERROR:
                        retry();
                        break;
                }
            }

            @Override
            protected void onError(@NonNull DatabaseError databaseError) {
                super.onError(databaseError);
                mSwipeRefreshLayout.setRefreshing(false);
                databaseError.toException().printStackTrace();
            }
        };

        //Set Adapter to RecyclerView
        mRecyclerView.setAdapter(mAdapter);

Just visit this below URL for reference https://firebaseopensource.com/projects/patilshreyas/firebaserecyclerpagination/app/readme.md/ Here you will find implementation of library which helps to implement Pagination of firebase data in RecyclerView

I hope this will help you!

Upvotes: 1

Ronny Bigler
Ronny Bigler

Reputation: 724

accepted answear dos not work when less then the max. itmes (21) in database. this is my solution build on the accepted answer:

0)set variables

        private String lastMessageKey;
    private int totalItemCount;
    private int lastVisibleItem;
    private boolean isLoadingMoreFollowers = false;
    private boolean hasMoreItems = true;
    private boolean hasShownNoMoreItemsToast = false;
    private boolean initialLoad = true;
    private final int MAX_LOAD_ITEMS = 11;
    private final int VISIBLE_TRESHOLD = 1;

1) set a listener:

       private void setMessageListener() {

        if (childEventListener == null) {

            mmessageArrayList.clear();
            final ArrayList<Mmessage> tempMmessages = new ArrayList<>();
            query = mDatabaseInstace.getReference().child(chat1).child(F.CHATS).child(F.MESSAGES).orderByKey().limitToLast(MAX_LOAD_ITEMS-1);
            childEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                    Log.d(TAG, "onChildAdded: -----------------> " + dataSnapshot);
                    Log.d(TAG, "onChildAdded: -----------------> " + s);

                    tempMmessages.add(dataSnapshot.getValue(Mmessage.class));
                    preloadMessagePics(tempMmessages);
                    if (initialLoad) {
                        lastMessageKey = tempMmessages.get(0).getMessagePushKey();
                        initialLoad = false;
                    }
                    mmessageArrayList.add(tempMmessages.size()-1, tempMmessages.get(0));
                    messageAdapter.notifyDataSetChanged();
                    tempMmessages.clear();


                }

                @Override
                public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                    Log.d(TAG, "onChildChanged: --------------------------------->");

                }

                @Override
                public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                    Log.d(TAG, "onChildRemoved: ---------------------------------->");

                }

                @Override
                public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                    Log.d(TAG, "onChildMoved: ------------------------------------>");

                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Log.d(TAG, "onCancelled: ------------------------------------->");

                }
            };
            query.addChildEventListener(childEventListener);
        }

    }

2) set load more listener:

        private void setLoadMoreListener(){
        setup.RV_messages.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);


                totalItemCount = linearLayoutManager.getItemCount();
                lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();



                if (!isLoadingMoreFollowers && totalItemCount <= (lastVisibleItem+VISIBLE_TRESHOLD) && (totalItemCount >= MAX_LOAD_ITEMS-1)){

                    if (hasMoreItems) {

                        getMoreMessages();
                        Toast.makeText(homeActivity, "load more items", Toast.LENGTH_SHORT).show();

                    }else {
                        if (!hasShownNoMoreItemsToast) {
                            Toast.makeText(homeActivity, "has no more items", Toast.LENGTH_SHORT).show();
                            hasShownNoMoreItemsToast = true;
                        }
                    }

                }

            }
        });
    }

3) get more items:

       private void getMoreMessages(){

        final ArrayList<Mmessage> tempMmessages = new ArrayList<>();

        isLoadingMoreFollowers = true;
        loadMoreQuery = mDatabaseInstace.getReference().child(chat1).child(F.CHATS).child(F.MESSAGES).orderByKey().endAt(lastMessageKey).limitToLast(MAX_LOAD_ITEMS);
        loadMoreChildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                tempMmessages.add(dataSnapshot.getValue(Mmessage.class));
                preloadMessagePics(tempMmessages);

                if (tempMmessages.size() == MAX_LOAD_ITEMS){

                    lastMessageKey = tempMmessages.get(0).getMessagePushKey();
                    Collections.reverse(tempMmessages);
                    tempMmessages.remove(0);
                    mmessageArrayList.addAll(tempMmessages);
                    isLoadingMoreFollowers = false;
                    messageAdapter.notifyDataSetChanged();
                    tempMmessages.clear();
                    return;
                }


                if (lastMessageKey.equalsIgnoreCase(tempMmessages.get(tempMmessages.size()-1).getMessagePushKey())){

                    Collections.reverse(tempMmessages);
                    tempMmessages.remove(0);
                    mmessageArrayList.addAll(tempMmessages);
                    isLoadingMoreFollowers = false;
                    hasMoreItems = false;
                    messageAdapter.notifyDataSetChanged();
                    tempMmessages.clear();

                }

            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        };
        loadMoreQuery.addChildEventListener(loadMoreChildEventListener);

    }

have fun!!

Upvotes: 0

Arnav Rao
Arnav Rao

Reputation: 7002

Android paging library can be used to implement pagination for data fetched from firebase database. Data is displayed in recycler view and paging component fetches pages in response to user scroll events.

Paging data source calls your firebase DAO object passing query parameters for the page to be displayed and results are passed back to paging component using callback provided to it.

Here is a complete example for reference http://www.zoftino.com/firebase-pagination-using-android-paging-library

Upvotes: 0

Kishan Solanki
Kishan Solanki

Reputation: 14636

This is how I implemented pagination from firebase database. Consider a case if we have 100 messages. So I first load last 20 messages from firebase i.e. 81 to 100. Then on scroll up I call getMoreMessages() function to load next 20 messages which are 61 to 80 and so on.

public class ChatActivity extends Activity {

        String chat_id = "";
        long mTotalChildren = 0;
        boolean loading = false;
        ChildEventListener childEventListenerMain, childEventListenerPager;
        ChatActivity mContext = ChatActivity.this;
        MessageAdapter messageAdapter;
        @BindView(R.id.pb_messages)
        ProgressBar pb_messages;
        @BindView(R.id.ll_audio)
        LinearLayout llAudio;
        @BindView(R.id.tv_record_time)
        AppCompatTextView tvRecordTime;
        @BindView(R.id.tv_cancel)
        AppCompatTextView tvCancel;
        @BindView(R.id.iv_send)
        AppCompatImageView ivSend;
        @BindView(R.id.iv_record)
        AppCompatImageView ivRecord;
        @BindView(R.id.ab_layout)
        AppBarLayout abLayout;
        @BindView(R.id.messages)
        RecyclerView rvMessages;
        @BindView(R.id.iv_chat_icon)
        SimpleDraweeView ivChatIcon;
        @BindView(R.id.iv_camera)
        AppCompatImageView ivCamera;
        @BindView(R.id.iv_gallery)
        AppCompatImageView ivGallery;
        @BindView(R.id.message_input)
        AppCompatEditText messageInput;
        @BindView(R.id.tv_send)
        AppCompatTextView tvSend;
        @BindView(R.id.toolbar_title)
        AppCompatTextView toolbarTitle;
        @BindView(R.id.toolbar_status)
        AppCompatTextView toolbarStatus;
        @BindView(R.id.ll_send)
        LinearLayout llSend;
        int categoryId, senderId, receiverId, offerId;
        String mLastKey;
        LinearLayoutManager layoutManager;
        private ArrayList<MessageModel> messageArrayList = new ArrayList<>();
        private ArrayList<MessageModel> tempMessageArrayList = new ArrayList<>();

        @Override
        public int getLayoutId() {
            return R.layout.activity_chat;
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            messageAdapter = new MessageAdapter(mContext, messageArrayList) {

            };

            layoutManager = new LinearLayoutManager(mContext);

            rvMessages.setLayoutManager(layoutManager);
            rvMessages.setItemAnimator(new DefaultItemAnimator());
            rvMessages.setAdapter(messageAdapter);
            rvMessages.setHasFixedSize(true);

            rvMessages.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                }

                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);

                    if (messageArrayList.size() >= 20 &&
                            !loading && layoutManager.findFirstVisibleItemPosition() == 0 && messageArrayList.size() < mTotalChildren) {

                        loading = true;
                        getMoreMessages();
                    }
                }
            });

            messageAdapter.notifyDataSetChanged();

            //used to scroll up recyclerview when keyboard pops up
            rvMessages.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View view, int left, int top, int right, int bottom,
                                           int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    if (bottom < oldBottom) {
                        rvMessages.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                rvMessages.scrollToPosition(messageArrayList.size() - 1);
                            }
                        }, 100);
                    }
                }
            });

            loading = true;
            getMessages();
        }

        public void getMessages() {

            FirebaseDatabase.getInstance().getReference().child(pathtomsgs).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    Log.e("childrenCount", String.valueOf(+dataSnapshot.getChildrenCount()));
                    mTotalChildren = dataSnapshot.getChildrenCount();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });


            Query messageQuery = FirebaseDatabase.getInstance().getReference().child(pathtomsgs).limitToLast(20);

            childEventListenerMain = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                    loading = true;
                    MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
                    if (messageModel != null) {
                        messageModel.chat_id = chat_id;
                        messageModel.message_id = dataSnapshot.getKey();
                        messageArrayList.add(messageModel);
                        messageAdapter.notifyDataSetChanged();
                        mLastKey = messageArrayList.get(0).message_id;
                        rvMessages.scrollToPosition(messageArrayList.size() - 1);
                    }
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Toast.makeText(mContext, "Problem loading more images...", Toast.LENGTH_LONG).show();
                }
            };

            messageQuery.addChildEventListener(childEventListenerMain);

            ValueEventListener messageChildSINGLEValueEventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    pb_messages.setVisibility(View.GONE);
                    System.out.println("We're done loading messages " + dataSnapshot.getChildrenCount() + " items");
                    loading = false;
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            };

            messageQuery.addListenerForSingleValueEvent(messageChildSINGLEValueEventListener);
        }

        public void getMoreMessages() {
            tempMessageArrayList.clear();

            Query messageQuery = FirebaseDatabase.getInstance().getReference().child(pathtomsgs).orderByKey().endAt(mLastKey).limitToLast(20);

            childEventListenerPager = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    loading = true;
                    MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
                    if (messageModel != null) {

                        messageModel.chat_id = chat_id;
                        messageModel.message_id = dataSnapshot.getKey();
                        tempMessageArrayList.add(messageModel);
                    }
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Toast.makeText(mContext, "Problem loading more images...", Toast.LENGTH_LONG).show();
                }
            };

            messageQuery.addChildEventListener(childEventListenerPager);

            ValueEventListener messageChildSINGLEValueEventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    System.out.println("We're done loading messages " + dataSnapshot.getChildrenCount() + " items");

                    tempMessageArrayList.remove(tempMessageArrayList.size() - 1);

                    messageArrayList.addAll(0, tempMessageArrayList);
                    mLastKey = messageArrayList.get(0).message_id;
                    messageAdapter.notifyDataSetChanged();
                    //rvMessages.scrollToPosition(20);
                    layoutManager.scrollToPositionWithOffset(19, 0);
                    loading = false;
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            };

            messageQuery.addListenerForSingleValueEvent(messageChildSINGLEValueEventListener);
        }


        @Override
        protected void onDestroy() {

            FirebaseDatabase.getInstance().getReference().child(pathtomsgs).removeEventListener(childEventListenerPager);
            FirebaseDatabase.getInstance().getReference().child(pathtomsgs).removeEventListener(childEventListenerMain);

            super.onDestroy();
        }
    }

Upvotes: 0

Shajeel Afzal
Shajeel Afzal

Reputation: 5953

I have following method to paginate through a firebase realtime database node:

private void getUsers(String nodeId) {
        Query query;

        if (nodeId == null)
            query = FirebaseDatabase.getInstance().getReference()
                    .child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
                    .orderByKey()
                    .limitToFirst(mPostsPerPage);
        else
            query = FirebaseDatabase.getInstance().getReference()
                    .child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
                    .orderByKey()
                    .startAt(nodeId)
                    .limitToFirst(mPostsPerPage);

        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                UserModel user;
                List<UserModel> userModels = new ArrayList<>();
                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                    userModels.add(userSnapshot.getValue(UserModel.class));
                }

                mAdapter.addAll(userModels);
                mIsLoading = false;
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                mIsLoading = false;
            }
        });
    }

Every time I reach the bottom of the paginated data, I call the getUsers(mAdapter.getLastItemId()); and then it brings the next set of records.

I have written a complete guide with open source sample app on this that you can check at https://blog.shajeelafzal.com/2017/12/13/firebase-realtime-database-pagination-guide-using-recyclerview/

Upvotes: 15

Vihaan Verma
Vihaan Verma

Reputation: 13143

Below is the code I'm using for pagination which shows the latest node first.

      public void getImages() {
            Query imagesQuery = FirebaseDatabase.getInstance().getReference().child("englishDps").child(mChildName).orderByKey().limitToLast(21);

            ChildEventListener childEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Image image = dataSnapshot.getValue(Image.class);
                    image.setNodeKey(dataSnapshot.getKey());

                    mTempImages.add(image);
                    if (mTempImages.size() == 21) {
                        mLastKey = mTempImages.get(0).getNodeKey();
                        Collections.reverse(mTempImages);
                        mTempImages.remove(mTempImages.size() - 1);
                        mImages.addAll(mTempImages);
                        setAdapter();
                    }
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    if (isAdded()) {
                        Toast.makeText(getActivity(), "Problem loading more images...", Toast.LENGTH_LONG).show();
                    }
                }
            };

            imagesQuery.addChildEventListener(childEventListener);
        }


  @Override
    public void getMoreImages() {
        if (!mGettingMoreImages) {
            mGettingMoreImages = true;
            Query imagesQuery = FirebaseDatabase.getInstance().getReference("englishDps").child(mChildName).orderByKey().endAt(mLastKey).limitToLast(21);

            ChildEventListener childEventListener = new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Image image = dataSnapshot.getValue(Image.class);
                    image.setNodeKey(dataSnapshot.getKey());
                    mMoreImages.add(image);
                    if (mMoreImages.size() == 21) {
                        mLastKey = mMoreImages.get(0).getNodeKey();
                        Collections.reverse(mMoreImages);
                        mMoreImages.remove(mMoreImages.size() - 1);
                        mImages.addAll(mMoreImages);
                        mMoreImages.clear();
                        mGettingMoreImages = false;
                        mImagesAdapter.notifyDataSetChanged();
                        return;
                    }

                    if (mLastKey.equalsIgnoreCase(image.getNodeKey())) {
                        Collections.reverse(mMoreImages);
                        mImages.addAll(mMoreImages);
                        mMoreImages.clear();
                        mGettingMoreImages = false;
                        mImagesAdapter.onNoMoreImages();
                        ;
                        mImagesAdapter.notifyDataSetChanged();
                    }
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    if (isAdded()) {
                        Toast.makeText(getActivity(), "Problem loading more images...", Toast.LENGTH_LONG).show();
                    }
                }
            };

            imagesQuery.addChildEventListener(childEventListener);
        }
    }

Upvotes: 18

Jayakrishnan
Jayakrishnan

Reputation: 4697

 mPageEndOffset = 0;
 mPageLimit = 10;


 mPageEndOffset += mPageLimit;

 deviceListQuery = mDatabase.child("users")
 .orderByChild("id").limitToFirst(mPageLimit).startAt(mPageEndOffset);

 deviceListQuery.addValueEventListener(YourActivity.this);

Upvotes: 4

crookful
crookful

Reputation: 57

You want to be using the limitToFirst/limitToLast methods to retrieve a limited number of results.

videosQuery.orderByKey().limitToFirst(20)

https://www.firebase.com/docs/web/api/query/limittofirst.html

You should really consider changing the naming convention of your videos to include leading 0s (i.e. video01, video02... video10, video11) because the above code will display them exactly as you have them above (which I assume is out of order?)

Alternatively, if you're adding the videos via Java, you could just let firebase create the uniqueids via push(). The uniqueid are generated in a way that they'll sort chronilogically, which sounds like it'll suit your need to grab the most recent(ly added?) videos.

https://www.firebase.com/docs/web/api/firebase/push.html

Upvotes: 4

Related Questions