Hammas Ali
Hammas Ali

Reputation: 9

Paginate new data over old data from firestore

I am building a chat app and using pagination in conversation screen. First i am loading ten messages the most recent one from firestore and then next 10 and goes on. when first 10 messages are loaded in screen the next 10 messages are loaded below the recent messages but i want to load old messages over new messages here is sample of my code

 toolbar =findViewById(R.id.toolbar5);
    toolbar.setTitle("");
    setSupportActionBar(toolbar);
    Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            finish();
        }
    });

    sendBtn = findViewById(R.id.sendBtn);
    textMsg = findViewById(R.id.txtMessage);
    profileImg=findViewById(R.id.profile_imageChat);
    userName = findViewById(R.id.userName);
    userState = findViewById(R.id.userState);
    refreshMessages = findViewById(R.id.refreshMessages);
    mChat = new ArrayList<>();


    firestore =FirebaseFirestore.getInstance();
    auth =FirebaseAuth.getInstance();
    docref = firestore.collection("users").document(getUser());
    documentReference = firestore.collection("users").document(Objects.requireNonNull(auth.getCurrentUser()).getUid());

    //setting up online and last seen status
    docref.addSnapshotListener(new EventListener<DocumentSnapshot>() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
            if(e!=null)
                Log.d("Event",e+"");
            if(documentSnapshot != null){
                if(documentSnapshot.getBoolean("state").equals(true))
                    userState.setText("Online");
                else
                    userState.setText(documentSnapshot.getString("offlineDate"));
            }
            else
                Log.d("Error","Null");
        }
    });

    refreshMessages.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            recieveMessage(auth.getCurrentUser().getUid(),getUser());
        }
    });

    sendBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String message = textMsg.getText().toString().trim();
            String sender=auth.getCurrentUser().getUid();
            if (!message.isEmpty()){

                //getting Current time
                calendar=Calendar.getInstance();
                @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm a");
                final String currentTime = simpleDateFormat.format(calendar.getTime());

                //getting current everything
                Calendar calendar2 = Calendar.getInstance();
                @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
                final String dateSet = simpleDateFormat1.format(calendar2.getTime());

                sendMessage(sender,getUser(),message,currentTime,dateSet);
            }
            else
                Toast.makeText(chatScreen.this,  "Error", Toast.LENGTH_SHORT).show();
            textMsg.setText("");
        }
    });

    constraintLayout=findViewById(R.id.toolbarLayout);
    constraintLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getApplicationContext(), userProfile.class);
            intent.putExtra("userid",getUser());
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplicationContext().startActivity(intent);
        }
    });


    docref.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(DocumentSnapshot documentSnapshot) {
            userName.setText(documentSnapshot.getString("Name"));

            recieveMessage(auth.getUid(),getUser());
            //Do coding For image
            storageReference = FirebaseStorage.getInstance().getReference();
            final StorageReference profile = storageReference.child("users/"+getUser());
            profile.getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    Picasso.get().load(task.getResult()).into(profileImg);
                }
            });
        }
    });

    //messages recycler view
    recyclerView =findViewById(R.id.recyclerSenderView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));

and here is the function i am calling from onCreate

 private void  recieveMessage(final String sender , final String reciever) {

    colref = FirebaseFirestore.getInstance().collection("chats");

    Query next;
    if(lastVisible == null)
        next = colref.orderBy("dateSet", Query.Direction.DESCENDING).limit(TOTAL_MESSAGES_TO_LOAD);
    else
        next = colref.orderBy("dateSet").limitToLast(TOTAL_MESSAGES_TO_LOAD).endBefore(lastVisible);

    next.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
            if(e!= null)
                Log.d("onEvent", e+"");
            if(queryDocumentSnapshots != null){

                // mChat.clear();
                //Load item first time
                for (QueryDocumentSnapshot ds : queryDocumentSnapshots){

                   lastvisibleDoc.add(queryDocumentSnapshots.getDocuments().toString());


                    if(ds.getString("Reciever").equals(sender) && ds.getString("Sender").equals(reciever) ||
                            ds.getString("Reciever").equals(reciever) && ds.getString("Sender").equals(sender)){

                        mChat.add(new ChatModel(ds.getString("Sender"),ds.getString("Reciever"),ds.getString("Message"),ds.getString("Time")));
                    }
                }

                // Get the last visible document
                if(queryDocumentSnapshots.size() > 0){
                    lastVisible = queryDocumentSnapshots.getDocuments().get(0);
                    Log.d("VisibleDoc",lastVisible+"");
                    lastvisibleDoc.clear();
                    Toast.makeText(chatScreen.this, "wrk", Toast.LENGTH_SHORT).show();
                }

                adapter =  new messgaeAdapter(getApplicationContext(),mChat);
                recyclerView.setAdapter(adapter);
                adapter.notifyDataSetChanged();

                recyclerView.scrollToPosition(mChat.size()-1);
                refreshMessages.setRefreshing(false);

            }
            else
                Log.d("Document","null");
        }
    });

}

Upvotes: 0

Views: 80

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598775

In that case you'll want to clear the list of messages by removing the comment markings from this line:

// mChat.clear();

This will remove the previous messages from the list, so that you only see the next page of messages.


I also recommend looking into this code:

adapter =  new messageAdapter(getApplicationContext(),mChat);
recyclerView.setAdapter(adapter);

These is no need to create a new adapter when loading the new messages. More idiomatic is to have these two lines in the onCreate so that they happen only once. When you then modify the contents of mChat, you'll call adapter.notifyDataSetChanged() (as you already do) to signal that the data has changed, and the adapter will update the recycler view.

Upvotes: 1

Related Questions