Reputation: 183
i am trying to make chat app but i have a problem with getting the realtime changes , i tried to use documentation and made the pagination successfuly but when i call addSnapshotListener i get all the documentation again not only the changes and when i tried to check the data that i get if is reapeted or not , the app crush ! i also trying to make it at the begining of the list , so any one can help me what is the wrong with my code!!
Get all List from firestore:
private void getList() {
String myId = mAuth.getUid();
String id = getIntent().getStringExtra("id");
messageItems = new ArrayList<>();
Query first = db.collection("ChatUsers")
.document(myId)
.collection(id)
.orderBy("time", Query.Direction.DESCENDING)
.limit(10);
first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots){
String name = documentSnapshot.get("name").toString();
String message = documentSnapshot.get("message").toString();
String messageId = documentSnapshot.getId();
String userId = documentSnapshot.get("userId").toString();
Long timee = (Long) documentSnapshot.get("time");
MessageItem messageItem = new MessageItem(message,messageId,name,userId,timee);
messageItems.add(messageItem);
adapter.notifyDataSetChanged();
}
if (queryDocumentSnapshots.size() >= 10) {
lastVisible = queryDocumentSnapshots.getDocuments()
.get(queryDocumentSnapshots.size() -1);
Query next = db.collection("ChatUsers")
.document(myId)
.collection(id)
.orderBy("time", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(10);
next.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots){
String name = documentSnapshot.get("name").toString();
String message = documentSnapshot.get("message").toString();
String messageId = documentSnapshot.getId();
String userId = documentSnapshot.get("userId").toString();
Long timee = (Long) documentSnapshot.get("time");
MessageItem messageItem = new MessageItem(message,messageId,name,userId,timee);
messageItems.add(messageItem);
}
addOnChangeListener(messageItems,id,myId);
lastVisible = queryDocumentSnapshots.getDocuments()
.get(queryDocumentSnapshots.size() -1);
}
});
}
}
});
}
here is what i get from changeListener:
private void addOnChangeListener(List<MessageItem> messageItems, String id, String myId) {
if (messageItems.size()>0){
db.collection("ChatUsers")
.document(myId)
.collection(id)
.orderBy("time", Query.Direction.ASCENDING)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
for (DocumentChange dc : value.getDocumentChanges()){
String name = dc.getDocument().get("name").toString();
String message = dc.getDocument().get("message").toString();
String messageId =dc.getDocument().getId();
String userId = dc.getDocument().get("userId").toString();
Long time = (Long) dc.getDocument().get("time");
MessageItem messageItem = new MessageItem(message,messageId,name,userId,time);
Log.i("messageId",messageId);
messageItems.add(0,messageItem);
adapter.notifyDataSetChanged();
}
}
});
}
}
Upvotes: 1
Views: 599
Reputation: 598728
What you're describing is the expected behavior: when you attach a snapshot listener, it reads all data that exists in the collection or that matches the query.
If you want to get a subset of that data, you should add conditions to your query to retrieve only that subset. For example, a common approach to get only data that is modified, is to store a lastModified
field in each document that you set to FieldValue.serverTimestamp()
, and then query for only documents where lastModified
is later than "now".
Upvotes: 3