Mohamed El Fwakhry
Mohamed El Fwakhry

Reputation: 183

addSnapshotListener gets all data again not the only changes

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

Answers (1)

Frank van Puffelen
Frank van Puffelen

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

Related Questions