Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parse.com datastore not pinning more than one unsaved object

Within a Task and without any internet connection, I am creating a ParseObject and referencing another ParseObject and the current user in it. I'm then pinning it to the local datastore, for saving later (these classes and the datastore are correctly initialised).

    final Rating rating = new Rating(substationObjectId, data);

    // inside constructor
    put(KEY_OTHER_OBJECT, OtherObject.createWithoutData(OtherObject.class, substationObjectId));
    put(KEY_USER, ParseUser.getCurrentUser());

    rating.pin("unsent");

I follow this up with a quick query to fetch all Ratings from that pin.

final ParseQuery<Rating> queryUnsent = ParseQuery.getQuery(Rating.class);
queryUnsent.whereEqualTo(Rating.KEY_USER, ParseUser.getCurrentUser());
queryUnsent.fromPin("unsent");
final List<Rating> unsentRatings = queryUnsent.find();

Logger.d(LOG_TAG, "queryUnsent count = %d", unsentRatings.size());
for (Rating unsentRating: unsentRatings) {
    Logger.d(LOG_TAG, "\tdatastore for %s with objectId='%s'", unsentRating().getName(), unsentRating.getObjectId());
}

The problem: only one Rating appears to be pinned. A second Rating is not stored, even though parse reports success.

First pinning (null objectId is ok and expected) of a Rating for 'Albury' yields these in a subsequent get-all query against the pin:

queryUnsent count = 1
datastore for Albury with objectId='null'

Second for 'Arapuni':

queryUnsent count = 1
datastore for Albany with objectId='null'

Other things tried:

  • pinEventually("unsent")
  • pin() without a label
  • save() immediately afterwards and discarding the connection exception
  • removing user=current user clause from everywhere
  • general queries against the datastore as a whole confirm that additional objects are not stored at all

After coming online and saving the Rating (which gives it an objectId), a new offline Rating will be pinned correctly but the problem then repeats itself with a second offline Rating.

I have a feeling it's a bug with parse.com's Android SDK library. It seems like the datastore is enforcing a unique constraint on objectId, but unsaved objects don't have an objectId yet.

Has anybody else run into this issue, or can suggest a work around?

like image 616
Tom Avatar asked May 10 '15 22:05

Tom


1 Answers

This is truly odd.

As I wrote in the comments my problems mainly involved getting unsaved objects unpinned, and so I started creating a project that would resemble some of the behavior in my app with a reproducible demonstration of the problem.

The Android Studio project can be found here: https://www.dropbox.com/sh/6whcw0qa1wdmnl2/AAAeELECIxgDjfa5ICULn2Zya?dl=0

About the project

The idea I have been trying to realize is to tie a task (ParseObject) together with a log entry (another ParseObject) and a JSONArray in a object called TaskSummaryHolder.

Having these 3 entities tied together locally, I can push a lot of information into the JSONArray and only periodically push the information from the JSONArray to the log entry.

The summary object that binds it all together are never meant to be stored online.

This scheme should be possible to apply to a range of different tasks so that one TaskSummaryHolder instance can store occurring events over a time period, while another keeps e.g. GPS entries.

Currently I have something somewhat similar to what is shown in the project in a live app, but due to the unpinning problem I am currently clearing the summaries instead of unpinning (removing columns and pinning).

Problem 1 unpinning

My first observation was that

ParseObject.unpinAllInBackground(TaskSummaryHolder.PIN)

Did not always work, whereas

ParseObject.unpinAllInBackground(TaskSummaryHolder.PIN, summaries)

Seemed more reliable. Just a bit strange if one has to query before unpinning if the goal is to purge a pin from the datastore.

Problem 2 pinning

To my surprise I encountered exactly the problem you describe. In the test project I fetch two tasks online and add a TaskSummaryHolder instance to each of them. Only the first instance got pinned locally.

Inspired by your description of the problem, I tried to let it pin and then save (see TaskSummaryHolder line 114).

After this it worked an have been unable to reproduce the problem from then on wards. Both pinning and unpinning behaved as expected even after uninstall and/or restart of phone.

It could be interesting if you would try and run the project and see how it behaves.

like image 136
cYrixmorten Avatar answered Oct 16 '22 16:10

cYrixmorten