简体   繁体   中英

How to fetch object and array fields with Parse?

I'm unable to properly fetch a ParseObject that contains a field of type 'Object' : after changing manually the 'Object' field value in the Parse DataBrowser and then fetch the ParseObject from the app, the fetched ParseObject still provide the old value for the 'Object' field, but provide the right new value for the 'String' field.

Here is the sample code I use :

public class MainActivity extends ActionBarActivity {

    ParseObject object;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        object = ParseObject.createWithoutData("Test", "tvgTg8jAXz");
    }


    @Override
    protected void onResume() {
        super.onResume();

        object.fetchInBackground().onSuccess(new Continuation<ParseObject, Object>() {
            @Override
            public Object then(Task<ParseObject> task) throws Exception {
                JSONObject data = task.getResult().getJSONObject("data");
                String name = task.getResult().getString("name");
                Log.d("OBJECT", data.toString());
                Log.d("OBJECT", name);
                return null;
            }
        }).continueWith(new Continuation<Object, Object>() {
            @Override
            public Object then(Task<Object> task) throws Exception {
                if (task.getError() != null) {
                    Log.e("OBJECT", task.getError().getLocalizedMessage());
                }
                return null;
            }
        });
    }
}

After I change both 'data' and 'name' fields in the DataBrowser, if 'onResume()' is called without a previous call to 'onCreate()' (after locking/unlocking screen for example) then the logs shows the old value for 'data' and the new value for 'name'.

This is a simple code example to highlight the problem I encounter in a bigger project.

Is this a known issue of the Parse Android SDK ? Is there a workaround ? Thanks

Now that I learned that you have turned on the local datastore I can come with an, at least partial, answer.

Turning on the local datastore has some side effects. One being that only one instance of each object exists locally. So when you call fetchInBackground the second time, object is already populated with data. The problem then (i think) is that the API no longer override 'complex' types (pointers, objects, arrays), perhaps because it could mess up internal relationships in the data store. Since the fact that the data store will recursively save an object (and pointers) so suddenly swapping a pointer might leave objects 'hanging'. (again, only guessing).

Now I must admit that it still confuses me a bit looking at your code, cause it does not seem that you at any point write your object to the data store, however..

What should work is to unpin the object before 'refreshing' it:

object.unpinInBackground.onSuccess(new Continuation<>{
    ...
    // when done call fetch
});

According to Parse, this is a known issue that they will not fix for now : https://developers.facebook.com/bugs/1624269784474093/

We must use the following methods to retrieve JSON objects/arrays fields from a ParseObject :

  • getMap() instead of getJSONObject()
  • getList() instead of getJSONArray()

These methods will return Map and List objects respectively. I found that managing Map and List in my project instead of JSONObjet and JSONArray is not a problem and is even clearer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM