ionic-team / ionic-storage

Ionic Storage module for Ionic apps
MIT License
437 stars 99 forks source link

Random data losses on iOS #317

Open graphefruit opened 7 months ago

graphefruit commented 7 months ago

Hey there, my application is using the ionic-storage. I've been reported since 1 week now by multiple users all on iOS that they have encountered random data losses. The application is tracking coffee, and each coffee results into one brew. Users tell me that some of the brews are missing, but strangly not ALL of them.

Funnyly enough I'm myself on iOS and I don't encouter this issue since months.

Also to mention, the code usage to access the database, storage things etc, haven't been change since more then 5 years, and now randomly this issue appears.

Also half year back, I realized that Apple shoot the database where the entries in the Database where corrupted and entries inside the array got corrupted - But this was from Update 17.1 to 17.2 - which I could fix with backups etc.

The storage driver which is used on the users side is logged as:

Storage-Driver: asyncStorage
 IonicStorageModule.forRoot({
      name: '__baristaDB',
      driverOrder: [
        Drivers.IndexedDB,
        CordovaSQLiteDriver._driver,
        Drivers.LocalStorage,
      ],
    }),

Versions:

"@ionic/cli": "^7.1.5",
"@ionic/storage": "^4.0.0",
"@ionic/storage-angular": "^4.0.0",
12.0.0 (cordova-lib@12.0.1)
 "@angular/common": "^16.2.7",
ios 7.0.0

I'd be happy if someone could give me a helping hand here what to try and how to get down to the issues root cause. Thank you so far Lars

graphefruit commented 7 months ago

The issue finally could be reproduced on a user side where I build in logs.

The thrown error is: "Error: Uncaught (in promise): UnknownError: Connection to Indexed Database server lost. Refresh the page to try again",

This error is referencing to this already reported bug: https://bugs.webkit.org/show_bug.cgi?id=197050

Somehow it also tells, that with iOS 17.4.X this issue has been increased much more, because before we didn't have this kind of issue.

I've also opend up a forum-ticket here: https://forums.developer.apple.com/forums/thread/750122?page=1#785564022

juhrlass commented 7 months ago

As this is obviously a problem with the underlying technology (IndexedDB) - What could be the best strategy to mitigate, workaround or fix the problem? Switch the storage Engine to something like this? https://github.com/capacitor-community/sqlite

graphefruit commented 7 months ago

As this is obviously a problem with the underlying technology (IndexedDB) - What could be the best strategy to mitigate, workaround or fix the problem? Switch the storage Engine to something like this? https://github.com/capacitor-community/sqlite

First: I think adding comments to the reported bug on webkit.org.

Also I changed my logic in code: I try to .get or .set in a loop and added a try catch block, if the catch block is triggered, I try it 10 times again, after that I try to reconnect the database (this.storage.create()), and try to access .get or .set again 10 times, if this is not working, I throw an error with a popup which can't be closed by the user, informing them whats happening and asking them to close or reload the application (button applied). All calls with a timeout of 100ms to not float.

Secondly, I've attached to the resume event.

this.platform.resume.subscribe

Then I access a database key, and if this one is failing I also throw an error popup. This will "solve" that users add data which can't be saved.

Also I've encountered that this issue is mainly when the application is minimized and opened up later again. Normally this issue didn't occure when first-starting the application.

banjerluke commented 6 months ago

My users are also being affected by this issue, though not via ionic-storage but Dexie (still IndexedDB though). FYI, I posted a new bug on bugs.webkit.org: https://bugs.webkit.org/show_bug.cgi?id=273827

lincolnthree commented 1 month ago

Also commented on the latest WebKit bug report. And many others before that, which have also failed to resolve this issue. Would love to see the Ionic team get involved here and try to help out with getting Apple to fix this. This has been an issue for years now.

A device restart seems to be the only consistent solution for the problem when it occurs, and only until it occurs again the next time.

Also I've encountered that this issue is mainly when the application is minimized and opened up later again. Normally this issue didn't occure when first-starting the application.

Same here. All sentry error reports on this seem to start with "App resumed from background".

graphefruit commented 1 month ago

A device restart seems to be the only consistent solution for the problem when it occurs, and only until it occurs again the next time.

My solution is written here:

Attach to this.platform.resume.subscribe Then I access a database key, and if this one is failing I also throw an error popup. This will "solve" that users add data which can't be saved. Also I've encountered that this issue is mainly when the application is minimized and opened up later again. Normally this issue didn't occure when first-starting the application.

This works since several month, myself got hit by this issue always a couple of times. A window.location.reload(); is enough, no ned for device restart gladly.

louis123562 commented 1 month ago

A device restart seems to be the only consistent solution for the problem when it occurs, and only until it occurs again the next time.

My solution is written here:

Attach to this.platform.resume.subscribe Then I access a database key, and if this one is failing I also throw an error popup. This will "solve" that users add data which can't be saved. Also I've encountered that this issue is mainly when the application is minimized and opened up later again. Normally this issue didn't occure when first-starting the application.

This works since several month, myself got hit by this issue always a couple of times. A window.location.reload(); is enough, no ned for device restart gladly.

I wouldn't say it is a solution, depending on the app or use case it is just a lazy workaround... I know several apps which do that and me as a user does not like that. Why should an app reload if the intention of iOS and Android is to persist the current state and load it on resume of an app??

graphefruit commented 1 month ago

I wouldn't say it is a solution, depending on the app or use case it is just a lazy workaround... I know several apps which do that and me as a user does not like that. Why should an app reload if the intention of iOS and Android is to persist the current state and load it on resume of an app??

You're right my wording was miss leading. I meant "solution" in this case as a "workaround" that is working.

lincolnthree commented 1 month ago

I wouldn't say it is a solution, depending on the app or use case it is just a lazy workaround... I know several apps which do that and me as a user does not like that. Why should an app reload if the intention of iOS and Android is to persist the current state and load it on resume of an app??

I stand by my wording ;) It's a solution, just not a good or acceptable one, LOL. Workaround is probably more fair. Regardless. We need a real fix for the underlying issue on iOS.

lincolnthree commented 1 month ago

Also, I'm surprised window.location.reload() works for you. Even fully restarting the App doesn't seem to solve it for our users.