Open nitikorndev opened 6 years ago
Update to the latest version, this assertion has been removed
@flovilmart Do you know root cause or step to make the crash happen I want to test after I update the latest SDK Thanks.
The runtime assertion has been removed so there’s no real way to force it now. See https://github.com/parse-community/Parse-SDK-iOS-OSX/pull/1266
@flovilmart I found the assertion still in the code
PFConsistencyAssert([oldObjectId isEqualToString:newObjectId], @"objectIds cannot be changed in offline mode.");
So basically this happens when you attempt to set an objectid on an existing object with the local datastore enabled. Previously, bolts would swallow all exceptions, now they are not. Are you using local datastore and live Query?
@flovilmart Yes, I enable isLocalDatastoreEnabled = true . but I didn't set any objectid to object. Do you know any cause that make the crash happen ?
@flovilmart Seem like the app try to merge the server data to local db and found the objectId change and that cause the app crash ? Is it can be the server issue ? Thanks for looking
Are you using liveQuery or the PFDecoders in your code? Or even creating objects directly from JSON?
@flovilmart NOW my team decide to disable offline mode. but when I change isLocalDatabase = false the user session gone I think I have to force logout Do you have any suggestion ? Thanks for take a look.
this is odd, the session should be stored into the keychain. But that’s probably a bad idea to disable local datastore without further investigation on your side of the implications. On my side I won’t have the time to look into this issue you encounter when disabling local datastore. I’ll probably have time to investigate the other issue at hand
Same issue here with 1.17.1. I use saveEventually() and get the same crash/error
I can reproduce a similar crash by calling saveEventually() followed by saveInBackground() with the local datastore enabled on a slow connection (simulated Edge). Was experimenting with this to force an immediate save with saveEventually().
I guess a conflicting objectId is created by the subsequent call of saveInBackground()?
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'objectIds cannot be changed in offline mode.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010ce3c1e6 __exceptionPreprocess + 294
1 libobjc.A.dylib 0x000000010c4d9031 objc_exception_throw + 48
2 CoreFoundation 0x000000010ceb1975 +[NSException raise:format:] + 197
3 Parse 0x0000000109c43976 -[PFOfflineStore updateObjectIdForObject:oldObjectId:newObjectId:] + 630
4 Parse 0x0000000109c07419 -[PFObject _notifyObjectIdChangedFrom:toObjectId:] + 265
5 Parse 0x0000000109c06d4d -[PFObject set_state:] + 461
6 Parse 0x0000000109c00f0d -[PFObject(Private) _mergeFromServerWithResult:decoder:completeData:] + 413
7 Parse 0x0000000109c00bf9 -[PFObject(Private) _mergeAfterSaveWithResult:decoder:] + 665
8 Parse 0x0000000109c01c86 __43-[PFObject(Private) handleSaveResultAsync:]_block_invoke + 150
9 Bolts 0x0000000106fa54c5 __37+[BFTask taskFromExecutor:withBlock:]_block_invoke + 69
10 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
11 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
12 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
13 Bolts 0x0000000106fa646c -[BFTask continueWithExecutor:block:cancellationToken:] + 860
14 Bolts 0x0000000106fa60d4 -[BFTask continueWithExecutor:withBlock:] + 116
15 Bolts 0x0000000106fa5424 +[BFTask taskFromExecutor:withBlock:] + 244
16 Parse 0x0000000109c0190a -[PFObject(Private) handleSaveResultAsync:] + 298
17 Parse 0x0000000109c4c5d9 __79-[PFPinningEventuallyQueue _didFinishRunningCommand:withIdentifier:resultTask:]_block_invoke.115 + 137
18 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
19 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
20 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
21 Bolts 0x0000000106fa646c -[BFTask continueWithExecutor:block:cancellationToken:] + 860
22 Bolts 0x0000000106fa6c94 -[BFTask continueWithBlock:] + 132
23 Parse 0x0000000109c4c08e __79-[PFPinningEventuallyQueue _didFinishRunningCommand:withIdentifier:resultTask:]_block_invoke + 974
24 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
25 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
26 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
27 Bolts 0x0000000106fa6b4a __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.126 + 42
28 Bolts 0x0000000106fa5ef2 -[BFTask runContinuations] + 754
29 Bolts 0x0000000106fa56cc -[BFTask trySetResult:] + 252
30 Bolts 0x0000000106fa7cb9 -[BFTaskCompletionSource setResult:] + 89
31 Bolts 0x0000000106fa676d __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 525
32 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
33 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
34 Bolts 0x0000000106fa6b4a __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.126 + 42
35 Bolts 0x0000000106fa5ef2 -[BFTask runContinuations] + 754
36 Bolts 0x0000000106fa56cc -[BFTask trySetResult:] + 252
37 Bolts 0x0000000106fa7cb9 -[BFTaskCompletionSource setResult:] + 89
38 Bolts 0x0000000106fa68f1 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 353
39 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
40 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
41 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
42 Bolts 0x0000000106fa6b4a __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.126 + 42
43 Bolts 0x0000000106fa5ef2 -[BFTask runContinuations] + 754
44 Bolts 0x0000000106fa56cc -[BFTask trySetResult:] + 252
45 Bolts 0x0000000106fa7cb9 -[BFTaskCompletionSource setResult:] + 89
46 Bolts 0x0000000106fa68f1 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 353
47 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
48 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
49 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
50 Bolts 0x0000000106fa6b4a __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.126 + 42
51 Bolts 0x0000000106fa5ef2 -[BFTask runContinuations] + 754
52 Bolts 0x0000000106fa56cc -[BFTask trySetResult:] + 252
53 Bolts 0x0000000106fa7cb9 -[BFTaskCompletionSource setResult:] + 89
54 Bolts 0x0000000106fa68f1 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 353
55 Bolts 0x0000000106fa65c8 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 104
56 Bolts 0x0000000106fa1fd9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 185
57 Bolts 0x0000000106fa297e -[BFExecutor execute:] + 94
58 Bolts 0x0000000106fa6b4a __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.126 + 42
59 Bolts 0x0000000106fa5ef2 -[BFTask runContinuations] + 754
60 Bolts 0x0000000106fa56cc -[BFTask trySetResult:] + 252
61 Bolts 0x0000000106fa7cb9 -[BFTaskCompletionSource setResult:] + 89
62 Bolts 0x0000000106fa68f1 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 353
63 Bolts 0x0000000106fa66d1 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 369
64 libdispatch.dylib 0x000000010e2d47ec _dispatch_client_callout + 8
65 libdispatch.dylib 0x000000010e2db55c _dispatch_queue_barrier_sync_invoke_and_complete + 374
66 Parse 0x0000000109c88fb7 PFThreadsafetySafeDispatchSync + 151
67 Parse 0x0000000109c81a63 __33-[PFSQLiteDatabase initWithPath:]_block_invoke_2 + 35
68 libdispatch.dylib 0x000000010e2d37ab _dispatch_call_block_and_release + 12
69 libdispatch.dylib 0x000000010e2d47ec _dispatch_client_callout + 8
70 libdispatch.dylib 0x000000010e2e061d _dispatch_root_queue_drain + 1353
71 libdispatch.dylib 0x000000010e2e0076 _dispatch_worker_thread3 + 132
72 libsystem_pthread.dylib 0x000000010e7ff169 _pthread_wqthread + 1387
73 libsystem_pthread.dylib 0x000000010e7febe9 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
@andreasvestergaard thanks for the report this is very interesting and yes that's likely to be the cause.
Now I'm left wondering how we can properly solve the issue. As we send two save command, it is normal that two HTTP calls are sent. The second save response is causing the issue as the first one succeeded and stored the object in the store.
My big question is which object should we keep? the last successfully saved one or the first one and dropping the second response as both are responses for the same save intent in this case.
@flovilmart You’re very welcome. Thanks for looking into it.
I would say keep the object which is created by the last save command. That object could be successfully saved first or last as both functions are asynchronous, right?
That would ensure any updates made to the object between the first and the second call would get saved.
I ran in to this issue trying to force an immediate save to the server and the local datastore while falling back to saveEventually() if there's no connection. This is my current workaround which seems to work:
object.pinInBackground()
object.saveInBackground { (success, error) in
if success == false {
object.saveEventually()
}
}
That’s not very convenient as a workaround. Are you willing to attempt a PR with the change? As you have the issue and can reproduce, we can attest of the fix :)
It's definitely not pretty :) Would love to contribute and fix it but after taking a closer look in PFObject.m I probably wouldn't be able to at the moment.
My 2 cents would be to tweak saveEventually() to save objects immediately if possible. Like saveInBackground() does it.
As a user friendly long term solution i would deprecate one of the functions and have just one for saving an object to the server. This function would
I probably wouldn't be able to at the moment
If you don't try, you'll never know.
i would deprecate one of the functions and have just one for saving an object to the server.
I'm not sure this would solve the issue at all.
I can pick up this and help with this issue. @flovilmart Just tell me what would be the best way to fix it?
I can include @andreasvestergaard workaround inside saveInBackground
and pinObjectAutomatically if localStoreEnabled?
@neil-degoo I am not sure actually.
@flovilmart who is the best candidate to discuss with?
As it stands in the discussion, the preferred resolution would be not to crash.
It is known for slow operations that two saves may result in a crash as the object to be saved is added twice to the local data store, instead of once.
We could check that the two objects are consistent and not crash if both are valid. We could also check the updatedAt property, and keep the most recently updated one.
Hi, I'm experiencing the same issue. Any progress made here? Thanks
So I know that this hasn't been discussed in a long time. I'm curious if anyone is still having issues with the latest version 1.17.3?
I experienced this issue for the first time this week, and it's happening fairly often for me now with a newly staged server.
iOS Client code has remained the same, Parse server was upgraded from 4.2.0 to 5.2.0.
I'll do some testing to see what I can find out.
Hi, my app crashes a lot in a past few week affect many users but I can't not find step to reproduce this crash. Anyone got the same issue ?