Я веду чат, используя Firebase для хранения сообщений и RecyclerView для их отображения. Согласно приведенному ниже коструктору адаптера, когда RecyclerView инициализируется, последние 50 сообщений запрашиваются из Cloud Firestore и располагаются в порядке убывания по временной метке Unix. Затем я использую setStackFromEnd (true) в своем чате, чтобы изменить порядок их отображения, так как самые новые сообщения должны быть внизу, а новые сообщения добавляются в список сообщений адаптера с помощью messageList.add (0, message)
Это представляет проблему. В onBindViewHolder ранее приемлемые:
Message message = messageList.get(position);
holder.message.setText(message.getMessage());
holder.author.setText(message.getAuthor() + ":");
Больше не работает, потому что сообщение, вводимое в RecyclerView, будет повторением самого последнего сообщения при загрузке RecyclerView (то есть в позиции 0). то есть:
Вместо того:
Где «message one» - самое последнее сообщение при создании RecyclerView. Заменив это на:
Message message = messageList.get(0);
holder.message.setText(message.getMessage());
holder.author.setText(message.getAuthor() + ":");
В onBindViewHolder, чтобы получить истинное самое последнее сообщение, оно будет отображаться на экране, но также впоследствии заменит все элементы самым последним сообщением, когда они будут переработаны. В конечном итоге я хотел бы, чтобы запрошенные сообщения перечислялись снизу вверх в порядке недавности, продолжая размещать самые новые сообщения внизу (как и любое приложение для чата), без необходимости запрашивать всю коллекцию. Где и как исправить ошибку?
Конструктор адаптера:
public ChatRecyclerViewAdapter(Context mContext, ArrayList<String> mMessage, ArrayList<String> mAuthor, String mRoomID, FirebaseFirestore firestore) {
messageList = new ArrayList<>();
firestore = FirebaseFirestore.getInstance();
mCollection = firestore.collection(mRoomID + "_messages");
Query query = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).limit(50);
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
switch (documentChange.getType()) {
case ADDED:
documentChange.getDocument();
Message message = documentChange.getDocument().toObject(Message.class);
messageList.add(0,message);
notifyItemInserted(messageList.size());
}
}
}
});
Попытка запросить следующий набор сообщений старого набора при прокрутке:
query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (queryDocumentSnapshots.size() > 0) {
//Get the last visible document
DocumentSnapshot lastVisible = queryDocumentSnapshots.getDocuments().get(messageList.size()-1);
//Construct a new query starting at this document and get the next batch of messages
Query next = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).startAfter(lastVisible).limit(20);
next.get();
}
}
});




Проблема в вашем коде заключается в том, что вы сортируете по убыванию, используя Unix timestamp, а не объект Date. Чтобы заставить его работать, я рекомендую вам изменить способ хранения метки времени на Date. По этому поводу см. Мой ответ из этого Почта, где я объяснил, как этого можно добиться с помощью POJO class или Map.
Здесь вы можете найти руководство о том, как создать Приложение для чата, где я объяснил то же самое, что вы ищете. См. Снимок экрана ниже:
В моем коде я использовал в качестве запроса следующую строку кода:
val query = rootRef!!
.collection("messages")
.document(roomId)
.collection("roomMessages")
.orderBy("sentAt", Query.Direction.ASCENDING)
Давайте придерживаться одного вопроса за раз. Это звучит как новая проблема, которую, по сути, следует рассматривать как еще один вопрос, на который нельзя ответить в комментариях. Чтобы следовать правилам этого сообщества, отправьте еще один свежий вопрос, чтобы я и другие пользователи могли вам помочь.
В качестве личной подсказки, это - это рекомендуемый способ разбивки запросов на страницы путем комбинирования курсоров запросов с методом limit (). Я также рекомендую вам взглянуть на этот видео для лучшего понимания.
Если вы считаете, что мой ответ и рекомендация вам помогли, рассмотрите возможность принятия (✔️) моего ответа и проголосуйте за (?). Я бы оценил это. Спасибо!
Спасибо. Я попробую это и опубликую новый вопрос, если у меня все еще будут проблемы.
Извините, я упустил некоторые важные детали. В конечном итоге я хочу иметь возможность разбивать сообщения согласно документации на страницы, чтобы получать больше сообщений, когда пользователь прокручивает самое старое сообщение. Для этого я добавил начало своего кода. Я отсортировал по убыванию, чтобы самые последние сообщения загружались первыми, когда я использовал .limit (). Сортировка по возрастанию с ограничением загружает самые старые сообщения и ничего более, причем самое старое сообщение находится в позиции [0], которое всегда будет видно при загрузке.