3

I'm storing objects to the Parse local datastore in the standard manner:

[someObject pinInBackgroundWithName:someName];

Generally, this works fine. However, sometimes when I do a local query, i.e.

PFQuery *query = [SomeObject query]; 
[query fromLocalDatastore];
[query fromPinWithName:someName];
[query findObjectsInBackgroundWithBlock:block];

it appears there are no local objects and I get the error:

error   NSError *   domain: @"Parse" - code: 120

which I understand to be:

"Error code indicating the result was not found in the cache."

I thought the local datastore and the cache were 2 completely different storage mechanisms? Yet it seems my data is being saved to the cache, which is then being flushed. How could this be? The local datastore isn't much use if it gets flushed out of my control...

UPDATE

I thought initially it was because I was accessing the local datastore while writing to it in the background, therefore getting a nil result. But putting my pinning onto the main thread doesn't resolve this.

Then I thought it might be a bug with recursive pinning, since my object contains pointers to objects with pointers. But explicitly pinning all pointers didn't help - whether in the background or on the main thread.

I tried just querying the object without the includeKey, and I think this meant consistent returns, but the secondary query needed to retrieve the remaining data proved a bit slow for what I'm trying to do.

Finally, I think it might be something to do with this bug

Writing any new data appears to remove all the previous pinned data...

Smikey
  • 8,106
  • 3
  • 46
  • 74
  • It's true that the local datastore and the cache are mutually exclusive. I don't know why you might be losing objects. – Daniel Zhang Nov 18 '15 at 22:59
  • Not exactly sure if that is the cause but could it be that some of the object have not been fetched yet. This is from the api documentation "If those other objects have not been fetched from Parse, they will not be stored. " https://parse.com/docs/ios/api/Classes/PFObject.html#//api/name/pinInBackgroundWithName: – Yan Nov 19 '15 at 00:45
  • Hmm, well the object itself, not just the objects it references, isn't even being stored. And I know the objects have been fetched because I can see their properties being displayed correctly. The thing is, the objects are stored and retrieved fine, until for some reason they seem to be wiped. Or at least the query searches the cache instead, and returns nothing... – Smikey Nov 19 '15 at 09:22
  • 1
    Maybe the same problem . https://groups.google.com/forum/#!topic/parse-developers/ZsXQYKiegyo – PowHu Dec 01 '15 at 09:25
  • Thanks for the link - the problems looks similar for sure, although none of the solutions work for me yet... am investigating and will report back. – Smikey Dec 01 '15 at 11:46

3 Answers3

0

Please check the query limit used to request/storing objects from parse since the default limitSize = 100 and set it to the max of 1000 (maximum of 1000 results being returned at a time).

[query setLimit: 1000]; //the default is 100.
Idali
  • 1,023
  • 7
  • 10
  • But I'm only requesting around 27 objects max. So it's way below the 100 limit. It can't be anything to do with the limit. – Smikey Nov 30 '15 at 21:48
  • are you using Anonymous User creation – Idali Dec 01 '15 at 14:33
  • are you using Anonymous User access? if so, then if the the current AnonymousUser is nil or if you created new one, you will no longer have access to old pined object of that old User, a new data have to be requested and all old one should be flushed (unpinAllObjects & clearAllCachedResults) . – Idali Dec 01 '15 at 14:58
  • I don't think I'm using anonymous user access... I haven't enabled it anywhere, and I have users attached to all my data. – Smikey Dec 01 '15 at 15:07
0

Update: I'm now pretty sure that the nil returns were because I was including keys for objects that hadn't been fetched. So instead of returning an array of objects with nil objects attached, it just returns nil. So if you're querying the local datastore with a bunch of include keys, make sure all the included data exists in the local datastore first. Otherwise it returns nil.

Original answer:

I haven't managed to figure this out, but there is a work-around. I was trying to avoid having to use it, but after days of fiddling, it seems the only solution.

Don't include any 'includeKey's in the original query. Doing so, in my case at least, seems to wipe the local datastore. Any subsequent queries work fine, but if you quit the app and re-open it, or write any new data, the first query always wipes the store and returns nil objects.

So instead, query on a single object and then fetchFromLocalDatastore when you need to access anything it points to.

I found advice here and here (thanks @PowHu) but I could find little else online about the issue.

Smikey
  • 8,106
  • 3
  • 46
  • 74
  • Further investigation suggests - ok to includeKeys in local queries, but not keys of keys (i.e. includeKey:@"something.other"). Fine to do so for online queries. – Smikey Dec 16 '15 at 17:25
0

You try to pin object that holds pointers to other objects. This is a parse.com local data store bug! here is a workaround:

Try to first pin the inner object and only after that pin the wrapper object.

Shai Balassiano
  • 997
  • 2
  • 10
  • 21
  • Thanks @hershalle - can the pointers be pinned in the background or do they have to be on the main thread, to ensure the wrapper object is only pinned once they are? – Smikey Feb 23 '16 at 13:38