androidparse-platformlocal-datastoreandroid-parsequeryadapter

Querying local datastore in using ParseQueryAdapter gives 0 results even after successfully pinning


Background:
I am working on a group messaging app for Android using parse.com as my backend.

Working:

  1. I Have a ParseQueryAdapter which queries for ChatGroups from the local datastore using:

    public ChatGroupAdapter(final Context context) {
           super(context, new ParseQueryAdapter.QueryFactory<ChatGroup>() {
              public ParseQuery<ChatGroup> create() {
                  ParseQuery<ChatGroup> chatGroupQuery = ParseQuery.getQuery(ChatGroup.class);
                  chatGroupQuery.fromLocalDatastore();
                  Log.d(ChatGroup.class.getName(), "Constructor query: " +  
                  chatGroupQuery + " made");
                  //noinspection unchecked
                  return chatGroupQuery;
              }
       });
    }
    
  2. The fragment that contains it listens to it by adding a ParseQueryAdapter.OnQueryLoadListener. If the ParseQueryAdapter cannot retrieve the ChatGroups from the local datastore, it retrieves it from parse, pins it and then triggeres the ParseQueryAdapter to retry loading from the local datastore using: .loadObjects();. Here is a code snippet from my fragment:

    @Override
        public void onLoaded(List<ChatGroup> groups, Exception e) {
            l.d("onLoaded called");
            if (e != null) {
                e.printStackTrace();
                updateLocalDatastore();
            } else if (groups == null) {
                l.w("Received null group list.");
                updateLocalDatastore();
            } else if (groups.size() == 0) {
                l.w("Received group list of size zero.");
                updateLocalDatastore();
            } else {
                l.d("Chat groups loaded successfully");
            }
        }
    
    private void updateLocalDatastore() {
        final ParseQuery<ChatGroup> groupQuery = ParseQuery.getQuery(ChatGroup.class);
        groupQuery.findInBackground(new FindCallback<ChatGroup>() {
            @Override
            public void done(final List<ChatGroup> chatGroupList, ParseException e) {
                if (e != null) {
                    e.printStackTrace();
                } else {
                    if (chatGroupList != null) {
                        ParseObject.pinAllInBackground(chatGroupList, new SaveCallback() {
                            @Override
                            public void done(ParseException e) {
                                if (e != null) {
                                    e.printStackTrace();
                                } else {
                                    l.d("Successfully pinned: " + chatGroupList.size() +
                                            " groups to local datastore. Reloading adapter");
                                    groupAdapter.loadObjects();
                                }
                            }
                        });
                    } else {
                        l.e("Received null group list from cloud! " +
                                "Local datastore update failed!");
                    }
                }
            }
        });
    }
    

Result:
And here is a simplified log of the execution:

ChatFragment: onCreate
ChatFragment﹕ Initializing chat groups
ChatFragment﹕ Loading chat groups
ChatFragment: onStart
ChatFragment: onResume
ChatFragment﹕ onLoaded called
ChatFragment﹕ Received group list of size zero.
ChatFragment﹕ Successfully pinned: 3 groups to local datastore. Reloading adapter
ChatFragment﹕ Loading chat groups
ChatFragment﹕ onLoaded called
ChatFragment﹕ Received group list of size zero.
ChatFragment﹕ Successfully pinned: 3 groups to local datastore. Reloading adapter
ChatFragment﹕ Loading chat groups
ChatFragment﹕ onLoaded called
ChatFragment﹕ Received group list of size zero.
ChatFragment﹕ Successfully pinned: 3 groups to local datastore. Reloading adapter
ChatFragment﹕ Loading chat groups
ChatFragment﹕ onLoaded called
ChatFragment﹕ Received group list of size zero.

It seems obvious to me that the ParseQueryAdapter should retrieve a list of 0 the first time which triggers the updateLocalDatastore() which pulls 3 ChatGroups from parse, pin them and then it should receive 3 from the local datastore. However as seen in the log, it continues to find 0 ChatGroups from the local datastore even after pinning them successfully!

The project setup seems fine:

Parse.enableLocalDatastore(this);
Parse.initialize(this, AppProps.properties.appId, AppProps.properties.clientKey);
ParseUser.enableRevocableSessionInBackground();
Parse.setLogLevel(Parse.LOG_LEVEL_DEBUG);
ParseObject.registerSubclass(ChatGroup.class);

What am I doing wrong?! Am I missing something?

I implemented the exact same logic with ParseUser and it worked flawlessly! There seems to be something wrong with doing the same with GroupChat:

@ParseClassName("ChatGroup")
public class ChatGroup extends ParseObject {

Some say that it is a parse bug with relations in the local datastore. But I am not even using relations. Even a simple query from the local datastore doesn't work.


Solution

  • Although I couldn't fix the problem, I discovered what the issue was. The issue is related to an underlying bug with the Parse SDK of Android: ParseQuery gives 0 objects when querying from local datastore even after successfully pinning