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 the ParseQueryAdapter
cannot retrieve the ChatGroup
s 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 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