Grabenkind
Grabenkind

Reputation: 15

Firestore chat messages are not in the right order?

So, I'm still a newbie in Firebase and I'm just switching from the Firebase Realtime Database to Firestore. This has worked out well so far. But I have a problem with the messages from my chat app. With the Firebase Realtime Database everything worked fine, but with Firestore there are some problems. I can send and display the messages, but Firestore somehow changes the order of the chat. Could someone explain this to me and suggest a solution?

Example video of the bug: https://youtu.be/KE28qK22DoQ

(Adapter) MessageAdapter: https://hastebin.com/avoluximow.java

(Model) Chat: https://hastebin.com/secuvojoyu.java

This is my code for writing and reading the data:

private void sendMessage(String sender, String receiver, String message) {
    FirebaseFirestore db = FirebaseFirestore.getInstance();

    HashMap<String, Object> chat = new HashMap<>();
    chat.put("sender", sender);
    chat.put("receiver", receiver);
    chat.put("message", message);

    db.collection("chats").add(chat);
}

private void readMessages(final String myid, final String userid) {
    mChat = new ArrayList<>();
    FirebaseFirestore db = FirebaseFirestore.getInstance();

    db.collection("chats")
            .addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot value,
                                    @Nullable FirebaseFirestoreException e) {
                    if (e != null) {
                        Log.w(TAG, "readMessages - Reading data failed", e);
                        return;
                    }

                    mChat.clear();
                    for (QueryDocumentSnapshot document : value) {
                        Chat chat = document.toObject(Chat.class);
                        if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
                                chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) {
                            mChat.add(chat);
                        }

                        messageAdapter = new MessageAdapter(MessageActivity.this, mChat);
                        recyclerView.setAdapter(messageAdapter);
                    }
                }
            });
}

Upvotes: 1

Views: 810

Answers (1)

walkmn
walkmn

Reputation: 2391

Try to add new field (when sending message):

chat.put("created", Timestamp.now());

And add field to your entity Chat.java:

private Timestamp created;

public Timestamp getCreated() {
    return created;
}

And before creating adapter add sort the list by this field:

Chat chat = document.toObject(Chat.class);
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
        chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) {
    mChat.add(chat);
}
// sorting by date >
Collections.sort(mChat, new Comparator<Chat>() {
    @Override
    public int compare(Chat o1, Chat o2) {
        return o1.getCreated().compareTo(o2.getCreated());
    }
});
// ^
messageAdapter = new MessageAdapter(MessageActivity.this, mChat);
recyclerView.setAdapter(messageAdapter);

Upvotes: 1

Related Questions