Порядок ArrayList изменяется при обновлении из базы данных Firestore - PullRequest
0 голосов
/ 27 ноября 2018

Проблема: Элементы моего списка отображаются в неправильном порядке.Это происходит, когда я закрываю фрагмент и снова открываю его.Затем сначала отображаются все «отправленные сообщения», а затем полученные сообщения.Тем не менее, когда я пишу сообщения, они появляются в правильном порядке.Только когда я закрываю фрагмент / действие и заново открываю его, порядок изменился.

Я вызываю метод getMessages в моем методе on-create для открытия фрагмента, содержащего представление.

Что я пробовал:

  • Использование метода Firestore orderby (как с String, так и TimeStamp)
  • Использование более простогоСлушатель моментальных снимков Firestore

Вопрос:

  • Как лучше всего использовать прослушиватель моментальных снимков Firestore с RecyclerView и правильно поддерживать порядок элементов?

Вот мой основной метод getMessages:

public void getLiveChatMessages(final ArrayList<ChatConversationMessage> messageArrayList, final ChatConversationAdapter adapter, final String matchClicked) {

    final String userID = onboardingFirebaseUser.returnCurrentUserId();

    final CollectionReference messagesCollectionRef = db.collection("users")
            .document(userID)
            .collection("matches")
            .document(matchClicked)
            .collection("messages");

    messagesCollectionRef
            .orderBy("TimeStamp", Query.Direction.DESCENDING)
            .addSnapshotListener(new EventListener<QuerySnapshot>() {
                                     @Override
                                     public void onEvent(@Nullable QuerySnapshot value,
                                                         @Nullable FirebaseFirestoreException e) {
                                         if (e != null) {
                                             Log.w(TAG, "listen:error", e);
                                             return;
                                         }


                                         for (QueryDocumentSnapshot doc : value) {
                                             if (doc.get("Message") != null) {

                                                 if (doc.get("Message") != null && doc.get("From user with ID").equals(userID)) {
                                                     String message = doc.getString("Message");

                                                     messageArrayList.add(new ChatConversationMessage(message));
                                                     adapter.notifyDataSetChanged(); //Ensures messages are visible immediately

                                                 } else if (doc.get("Message") != null) {
                                                     final String message = doc.getString("Message");

                                                     DocumentReference matchRef = db.collection("users")
                                                             .document(userID)
                                                             .collection("matches")
                                                             .document(matchClicked);

                                                     matchRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                                                         @Override
                                                         public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                                                             if (task.isSuccessful()) {
                                                                 DocumentSnapshot document = task.getResult();
                                                                 if (document.exists()) {
                                                                     imageReference = storageReference.child(document.getString("profileImg"));
                                                                     messageArrayList.add(new ChatConversationMessage(message, imageReference));
                                                                     adapter.notifyDataSetChanged(); //Ensures messages are visible immediately

                                                                 } else {
                                                                     Log.d(TAG, "No such document");
                                                                 }
                                                             } else {
                                                                 Log.d(TAG, "get failed with ", task.getException());
                                                             }
                                                         }
                                                     });

                                                 }
                                             }
                                         }
                                     }
                                 });}}

1 Ответ

0 голосов
/ 10 декабря 2018

Через некоторое время я обнаружил проблему.

Я вызывал метод get для новой ссылки в слушателе снимка.Когда вы делаете это, это влияет на порядок элементов в вашем ArrayList.

Чтобы решить эту проблему, убедитесь, что все элементы, необходимые вам из Firestore для создания ArrayList, хранятся в том же месте, что и поля в каждом документе (а не в двух разных местах).Таким образом, вам не нужно использовать отдельный метод get для новой ссылки в слушателе снимка.Это также обеспечивает чистоту кода на стороне клиента.Для будущих пользователей Google вот как я реструктурировал свой метод:

messagesCollectionRef
            .orderBy("TimeStamp", Query.Direction.ASCENDING)
            .addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot snapshots,
                                    @Nullable FirebaseFirestoreException e) {
                    if (e != null) {
                        Log.w(TAG, "listen:error", e);
                        return;
                    }

                    for (DocumentChange dc : snapshots.getDocumentChanges()) {

                        switch (dc.getType()) {
                            case ADDED:
                                Log.d(TAG, "New message added" + dc.getDocument().getData());

                                if (dc.getDocument().get("Message") != null && dc.getDocument().get("From user with ID").equals(userID)) {
                                    String message = dc.getDocument().getString("Message");
                                    messageArrayList.add(new ChatConversationMessage(CURRENTUSER, message, null));
                                    adapter.notifyDataSetChanged();
                                }

                                if (dc.getDocument().get("Message") != null && dc.getDocument().get("From user with ID").equals(matchClicked)) {
                                    String message = dc.getDocument().getString("Message");
                                    imageReference = storageReference.child(dc.getDocument().getString("profileImg"));
                                    messageArrayList.add(new ChatConversationMessage(OTHERUSER, message, imageReference));
                                    adapter.notifyDataSetChanged();
                                }
                                break;
                            case MODIFIED:
                                break;
                            case REMOVED:
                                break;
                        }
                    }
                }
            });

Как вы можете видеть, я теперь сохранил строку imageReference в каждом документе сообщения в Firestore, и его можно получить таким же образомЯ извлекаю все другие данные, которые мне нужны, чтобы добавить в мой ArrayList.Главное изменение кода, которое вам нужно сделать, - это то, где вы записываете свои данные в облако (т.е. пишете / устанавливаете документы Firestore).Вот где вам нужно убедиться, что все добавлено в документ в качестве значений полей, поэтому вам не нужно получать его в разных местах.Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...