Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paging Library in Chat App

According to a response made by Yigit Boyar from Google, Live Data is not the best use case for a chat app, because it may lose displaying some items if they come at the same time. He recommends using the new Google's Paging Library. I've been using ItemKeyedDataSource for my inbox(all the people that have message the user), and the inside chat(the messages themselves). The problems are the following:

1- From the chat, when the user scrolls downwards, the user retrieves old messages, which means that the insertion of those messages should be in position 0 of the adapter, not sequentially like the paging library does. How can I alternate the position of the inserted items to be sequentially for new messages, and in position 0 for old messages?

2- From the inbox(people that have message the user), again I'm using ItemKeyedDataSource here, the problem is that I want to maintain the multiple document listener from the repository (I'm using Firebase Firestore), so I can detect every time a new person talks to the user. The problem is that callback.onResult is called only once, and fails when Firebase sends another user. How can I maintain an update-able list?

like image 760
Andrey Avatar asked Jan 28 '23 04:01

Andrey


1 Answers

I understand that this answer is probably too late, but maybe it can help someone in future.

Position of item in RecyclerView is determined by the position of corresponding data object (of type T) inside PagedList<T>. PagedList is designed to look alike good old List<T>, but can be thought of as an "endless" list of elements.

PagedList gets its elements by pages on demand through something called DataSource.Factory. A Factory is used because DataSource by itself can only grow in one direction. If you need to prepend elements in PagedList, or change or remove existing elements you must invalidate the DataSource and a new instance will be created through DataSource.Factory.

So, to insert your data elements where you want them you should implement your own DataSource and DataSource.Factory by subclassing these base classes.

Note: Room, data persistence library from AndroidX, provides facilities to automatically generate instances of these classes for your data. You can write SQL query like this:

SELECT * FROM messages WHERE threadId=:threadId ORDER BY timestamp DESC

then get DataSource.Factory from this, use the factory to create LivaData<PagedList<Message>> and finally use the paged list to display messages in a RecyclerView in a chat application. Then, when you insert, update or remove data inside DB these changes will automatically propagate to the UI. This can be very useful.

I recommend you to read a few related examples a do codelabs:

  • https://codelabs.developers.google.com/codelabs/android-paging/#0
  • https://github.com/googlesamples/android-architecture-components/tree/master/PagingSample
  • https://github.com/googlesamples/android-architecture-components/tree/master/PagingWithNetworkSample
like image 188
Ivan Mikhnovich Avatar answered Feb 08 '23 00:02

Ivan Mikhnovich