0

Problem: The observer on LiveData<PagedList> is not triggered after the ItemKeyedDataSource.LoadedInitialCallback.onResult() is called.

At the time callback.onResult(...), the value passed in is correct. However, nothing happens after that.

Expected: After callback.onResult(...), the observer should be able to detect there is a change to LiveData.

Relevant Code: Method for fetching data from network (It's in a class called CommentManager), here we used Firestore:

...
public void loadInitialComments(int pageSize,
                                ItemKeyedDataSource.LoadInitialCallback<Comment> callback) {
    collectionReference.orderBy(DatabaseConstants.FIELD_TIMESTAMP)
        .limit(pageSize)
        .get()
        .addOnSuccessListener(queryDocumentSnapshots -> {
            callback.onResult(getComments(queryDocumentSnapshots));
        });
}
...

How the function is being called in DataSource class

...
@Override
public void loadInitial(LoadInitialParams<String> params,
                        LoadInitialCallback<Comment> callback) {
    commentManager.loadInitialComments(params.requestedLoadSize, callback);
}
...

ViewModel class

public final class CommentViewModel extends ViewModel {
    private final LiveData<PagedList<Comment>> comments;

    public CommentViewModel() {
        comments = new LivePagedListBuilder<>(new CommentDataSourceFactory(new CommentManager()), config).build();
    }

    public LiveData<PagedList<Comment>> getComments() {
        return comments;
    }

How ViewModel is called in main activity

...
CommentViewModel commentViewModel = new ViewModelProvider(this,
    new CommentViewModelFactory())
    .get(CommentViewModel.class);
commentViewModel.getComments().observe(this, comments -> commentListAdapter.submitList(comments));
...
Pranav Choudhary
  • 2,726
  • 3
  • 18
  • 38
  • I had a similar issue, for some reason in loadIntial asynchronous method doesn't work. you've to fetch the data synchronously at least for the loadInitial. – Parag Pawar Jul 14 '20 at 13:08
  • I see. 1. How do you do a synchronous data fetch on Firestore? 2. Is this the case only for loadInitial not for loadAfter and loadBefore? – 李孟阳 Jul 14 '20 at 13:16
  • Try from here: https://stackoverflow.com/questions/31700830/is-it-possible-to-synchronously-load-data-from-firebase – Parag Pawar Jul 14 '20 at 13:31
  • Thank you very much! I am able to do the synchronous data fetch. Now code in my DataSource class loadInitial method, I changed it to `List comments = commentManager.loadInitialComments(params.requestedLoadSize); callback.onResult(comments);` However, still nothing happens after `callback.onResult(comments)` – 李孟阳 Jul 14 '20 at 13:50
  • Have you tried debugging through out every step? Maybe put some logs in each step and check what values are you getting. – Parag Pawar Jul 14 '20 at 13:59
  • Also looks like you're trying to implement paging, check this article to get some hints: https://www.simplifiedcoding.net/android-paging-library-tutorial/ – Parag Pawar Jul 14 '20 at 14:00
  • The information I found during debugging: 1. the `getComment()` method in ViewModel class is called, at that time it returns null; 2. `loadInitial` in DataSource is called; 3. `loadInitial` in CommentManager is called and returned the correct values; 4. `callback.onResult()` is called and it's with the correct values; 5. The application continues and nothing happens. Thanks for the information provided. For the tutorial, it's with Retrofit, which I think is used for REST API. I haven't used Firestore REST API before, which might require major changes. Is that a more recommended approach? – 李孟阳 Jul 14 '20 at 14:16
  • No, don't use Retrofit, just see the structure of paging used in the library, like DataSourceFactoryClass and it's implementation in the ViewModel – Parag Pawar Jul 14 '20 at 14:21

0 Answers0