ParseQuery gives 0 objects when querying from loca

2019-07-19 06:20发布

问题:

I am using the Android SDK of parse.com and have arrived at a peculiar problem.

From a fragment's onCreate:

  1. Fetch an object from the server.
  2. Pin it.
  3. Fetch an object from the local datastore.

Here is a snippet of the code from the onCreate:

ParseObject myChatGroup = ParseObject.createWithoutData("ChatGroup", "mOJGWRiLPC");
    myChatGroup.fetchInBackground(new GetCallback<ParseObject>() {
        @Override
        public void done(ParseObject chatGroup1, ParseException e) {
            if (e == null) {
                l.d("Fetched chat group: " + chatGroup1 + " from server");
                chatGroup1.pinInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        if (e == null) {
                            l.d("Successfully pinned chat group");
                            ParseQuery<ParseObject> chatGroupParseQuery = new ParseQuery<>("ChatGroup");
                            chatGroupParseQuery.fromLocalDatastore()
                                    .findInBackground(new FindCallback<ParseObject>() {
                                        @Override
                                        public void done(List<ParseObject> list, ParseException e) {
                                            if (e == null) {
                                                l.d("Found " + list.size() + " chat groups from local datastore");
                                            } else {
                                                e.printStackTrace();
                                            }
                                        }
                                    });
                        } else {
                            e.printStackTrace();
                        }
                    }
                });
            } else {
                e.printStackTrace();
            }
        }
});

Here is the log:

Fetched chat group: ChatGroup { objectId: mOJGWRiLPC, name: Admin } from server
Successfully pinned chat group
Found 0 chat groups from local datastore

But this doesn't make any sense! I just pinned an object so how can there be 0 objects in the local datastore. The code is so simple. What am I doing wrong? Could it be a bug with the SDK?
Any insight will be much appreciated I have been trying to find the issue for days now.

The Parse setup looks fine to me:

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

Note:

  • It works fine when trying the same logic with the ParseUser object. And even other classes of mine like my Message which leads me to suspect that something is wrong with my ChatGroup class.
  • I have added two fields to my ChatGroup class on the parse.com data browser: name(String) and messages(Relation) with read and wrote access to a role called Admin.
  • When browsing to the actual parse db (using root access) I find that the database table (ParseObjects) does contain the row that I pinned. But somehow parse shows 0 results on querying it!

回答1:

Parse doesn't seem to support ACLs on local datastore. So the easiest way to get around this issue is to do ignoreACLs() on the query -- assuming you do have roles/acls setup correctly on the server side, so whatever you have pinned locally should be OK permission-wise already.



回答2:

I found the issue. It seems to be more like a bug with the Android SDK of parse. I narrowed it down to an issue with retrieving pinned objects with special ACLs using the Android SDK.

Initially, the object had the ACL such that only the role 'Admin' (that I created) can read and write. The funny thing is that the user with which I was testing the pinning and querying was an 'Admin'! But, when I changed the ACL such that public can read but only Admin can write, the problem was resolved!

My theory was that querying the local datastore behaves like a public query, no matter what role the user that is making the query has! But if any other theory explaining this would be appreciated. Luckily, in my case I need public read access, but this bug can be a huge downfall for some who need to have read access restricting ACLs! Hopefully parse.com will fix this issue soon.
This is quite a big issue! I am surprised that I couldn't find a question regarding this issue.



回答3:

Yeah so basically you have to set ACL for current user and pin it before you pin the chat group.

ParseACL acl = new ParseACL();
acl.setReadAccess(ParseUser.getCurrentUser(), true);
ParseUser.getCurrentUser().setACL(acl);
ParseUser.getCurrentUser().pinInBackground();