Background:
I am working on a group messaging app for Android using parse.com as my backend.
Working:
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; } }); }
The fragment that contains it listens to it by adding a
ParseQueryAdapter.OnQueryLoadListener
. If theParseQueryAdapter
cannot retrieve theChatGroup
s from the local datastore, it retrieves it from parse, pins it and then triggeres theParseQueryAdapter
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 ChatGroup
s 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 ChatGroup
s 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.
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