Reputation: 9
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
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