1

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);
                    }
                }
            });
}
Grabenkind
  • 15
  • 3
  • add your adapter code as well – Anuj Kumar Aug 11 '20 at 05:46
  • 1
    Here you can find a solution for a complete and functional [Firestore Chat App](https://www.youtube.com/playlist?list=PLn2n4GESV0Ak1HiH0tTPTJXsOEy-5v9qb), where the problem of ordering messages is solved. – Alex Mamo Aug 11 '20 at 06:08
  • @AlexMamo 1st: I use Java, 2nd: I want to understand what the Problem is, not just copy from a video. – Grabenkind Aug 11 '20 at 07:34
  • @AnujKumar I will do it right now – Grabenkind Aug 11 '20 at 07:34
  • @Grabenkind you need to sort mChat collection by date - https://stackoverflow.com/a/37291086/2738172, if you don't have date/time for messages, you can add this field in database. – walkmn Aug 11 '20 at 08:34
  • @walkmn I tried to understand how to use this example you linked, but I don't get it. But I think you can be right with the idea of sorting the list. Does Firebase Realtime Database do that automatically? – Grabenkind Aug 11 '20 at 10:42

1 Answers1

1

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);
walkmn
  • 2,322
  • 22
  • 29