lesnitsky / flutter_localstorage

πŸ“¦ LocalStorage for Flutter
MIT License
298 stars 65 forks source link

Data doesn't persist in latest version, does in 2.0.0 (android) #37

Closed nicoroy2561 closed 4 years ago

nicoroy2561 commented 4 years ago

Hi, I've been using this package but somehow with version 3.0.4 data wouldn't persist. here's my code:

final storage = LocalStorage('my_data.dart');

await storage.ready.then((_) => {myVar = storage.getItem("myVar")});

//if myVar is null I set it here~

tried running on my android 10 phone, data wouldn't persist, even if I installed the app. Tried changing my_data.dart to only my_data or anything else, wouldn't work as well. No error/exception was thrown either. On a whim I thought I'd try to update the pubspec and set the package's version to 2.0.0, that worked. Now the data is persisting between hot reloads as it should.

lesnitsky commented 4 years ago

@nicoroy2561 can you try to run https://github.com/lesnitsky/flutter_localstorage/tree/master/example on your device and let me know if it works?

nicoroy2561 commented 4 years ago

Tried running it, I get this:

Launching lib/main.dart on Mi 9T in debug mode... [!] Your app isn't using AndroidX. To avoid potential build failures, you can quickly migrate your app by following the steps on https://goo.gl/CP92wY. Invalid depfile: /Users/Roy/go/src/github.com/nicoroy2561/DM/demo_test/.dart_tool/flutter_build/b2f9474d2899a3d8e941253accdad8a9/kernel_snapshot.d Invalid depfile: /Users/Roy/go/src/github.com/nicoroy2561/DM/demo_test/.dart_tool/flutter_build/b2f9474d2899a3d8e941253accdad8a9/kernel_snapshot.d /Users/Roy/.gradle/caches/transforms-1/files-1.1/support-compat-28.0.0.aar/c3442e3e27884e7630b3c2089605bd2b/res/values/values.xml:133:5-70: AAPT: error: resource android:attr/fontVariationSettings not found.

/Users/Roy/.gradle/caches/transforms-1/files-1.1/support-compat-28.0.0.aar/c3442e3e27884e7630b3c2089605bd2b/res/values/values.xml:133:5-70: AAPT: error: resource android:attr/ttcIndex not found.

FAILURE: Build failed with an exception.

BUILD FAILED in 30s
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done 32.4s AndroidX incompatibilities may have caused this build to fail. Please migrate your app to AndroidX. See https://goo.gl/CP92wY. Gradle task assembleDebug failed with exit code 1

nicoroy2561 commented 4 years ago

I tried again with 3.0.0, data persists only while the app is open - upon restarting nothing that was set last time stays. rolling back again to earlier version. If you can help me understand how to properly set up the new version's example I will try it out.

lesnitsky commented 4 years ago

@nicoroy2561 I've checked out example both on android emulator and real device (Pixel 4XL) and it works fine... Could you please extract your code into small example project which demonstrates this issue?

lesnitsky commented 4 years ago

@nicoroy2561 fyi: I've recreated example app, check it out on your emulator/device

Maclaon commented 4 years ago

same issue! is it solved?

dupiesdupreez commented 4 years ago

This has not yet been solved

lesnitsky commented 4 years ago

@Maclaon @dupiesdupreez I'd be happy to solve this if I would have been able to reproduce this... Could someone create a reproducible example/share a complete code example that doesn't work?

lesnitsky commented 4 years ago

@nicoroy2561

somehow with version 3.0.4

Not sure how this is possible, the latest published version is v3.0.2

nicoroy2561 commented 4 years ago

I'm currently testing it. After running into the same problem again, I found a solution here: https://stackoverflow.com/questions/61436827/error-on-fluttersdkpath-packages-flutter-tools-gradle-app-plugin-loader-gradle which finally gets the build to pass on my device.

The example app works on my device. Will take a look and see what might be the cause of it not working on my app

nicoroy2561 commented 4 years ago

I tried changing your app around a bit, even having it point to version 3.0.0 (and not the rep's one directly) and it works. Which means that something is going wrong with the app I'm developing. I say that data isn't persisting because upon hot reload my app (which is configured to download data from a server only if not present on the device) keeps re-downloading it all. Which might be one of two things: either the data isn't saved on the device correctly (my first thought) or the newer version of the plugin takes significantly more time to initialize than version 2.0.0 (and returns null in the mean time?). Which might explain why on a hot reload my app isn't able to retrieve the data it needs. Could it also be because I am not instantiating the storage item on the main.dart file, but rather a file called by another file called by that file? (still it doesn't make sense that version 2.0.0 works and 3.0.0 doesn't.)

lesnitsky commented 4 years ago

@nicoroy2561 it would be great if you can provide a code snippet/demo app which demonstrates the issue

nicoroy2561 commented 4 years ago

@lesnitsky I know, and I wish I could. The problem is my app is fairly complex, so rearranging it into a "sample app" isn't feasible without a considerable amount of work. I can explain what it does with the plugin tho, and that might be useful. Maybe @Maclaon or someone else can provide a (non)working demo app.

Basically what my app does is it connects via websockets (within a file called ws.dart) to my server, and logs the user in.

That file imports data.dart, which contains final storage = LocalStorage('app_name.json'); (I tried adding new in front, removing the .json and all a bunch of other stuff too, to no avail with version 3.0.0). Also note that it is initialized as a global variable within that file (should it matter).

and then checks for the saved data. I tried, right after the connection, to print out the saved data, and the result was "null". As it is, the app then proceeds to ask the server for that user's data and download/save it offline. I tried killing the server and starting it again, forcing the app to reconnect to it (without hot reloading the app itself). The data stored was retrieved successfully this time: [18, 96, 332, 210, 3, Test] (it's a List < dynamic > ) So the problem seems to be only between app loads, as localstorage 3.0.0 is correctly handling stuff while the app is open. Not sure where I can find the file that should contain the data, but if you tell me I can look into it on my device and see if it gets written or not. I should also note that I'm never calling the dispose method on the localstorage instance, because it is used everywhere within the app. I checked and you're not doing it either on your demo app, so it might be of no concern.

Maclaon commented 4 years ago

@lesnitsky sorry, my mistake! the code snippet is very simple~

  static final LocalStorage localStorage = LocalStorage('app_data.json');
  static final User user = User.fromJson(localStorage.getItem('user'));

  static Future<void> initPlatformState() async {
    localStorage.stream.forEach((element) {print('see u: ' + element.toString());});
    localStorage.setItem('filter_movies', ['1',2,3]);
    try {
      if (Platform.isAndroid) {
        deviceData = _readAndroidBuildData(await deviceInfoPlugin.androidInfo);
      } else if (Platform.isIOS) {
        deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
      }
    } on PlatformException {
      deviceData = <String, dynamic>{
        'Error:': 'Failed to get platform version.'
      };
    }
  }

but, it will not persist anything when i restart my app! each time it looks like a new localStorage!

Maclaon commented 4 years ago

@lesnitsky can u take a glance at this issue?

lesnitsky commented 4 years ago

@Maclaon can you wrap localStorage.setItem with try catch and also add await before?

- localStorage.setItem('filter_movies', ['1',2,3]);
+ try {
+   await localStorage.setItem('filter_movies', ['1',2,3]);
+ } catch (err) {
+   print(err);
+ }
wfe8006 commented 4 years ago

@lesnitsky's snippet in https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart#L109-L119 definitely helped me fix the issue. Calling getItem in FutureBuilder(future: storage.ready works now

nicoroy2561 commented 4 years ago

Any way to do this outside of future builder? I mean, is there any way it can be integrated to the the storage.getItem call if called with await, rather than having it return a null value if it takes too long to initialize the library itself? Seems rather akward having to create a separate method that one can call and await upon to make sure it's been initialized, if it's as common as it appears to be.

To be clear, I'm a big fan of getItem not being async, but if that means I might get null even when a variable is set, is rather go with the async version.

2020εΉ΄6月1ζ—₯(月) 午後5:23 sotisoti notifications@github.com:

@lesnitsky https://github.com/lesnitsky's snippet in

https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart#L109-L119 definitely helped me fix the issue. Calling getItem in FutureBuilder(future: storage.ready works now

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lesnitsky/flutter_localstorage/issues/37#issuecomment-636920970, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANGJ7B2BGOGMB3SW45U4ZZDRUPBYDANCNFSM4LP2CLSA .

lesnitsky commented 4 years ago

localstorage initialization is asynchronous (since you have to read the contents of your storage from disk), that's why you should subscribe to ready and perform any reads/writes only after storage was initialized.

nicoroy2561 commented 4 years ago

I managed to get v3.0.0 working by awaiting on its readiness before fetching / updating data, so using a FutureBuilder or simply await should fix this. Apparently they changed something within the latest stable flutter update, as even v2.0.0 I had been using thus far wouldn't be loaded properly any longer now. Anyway, as it seems to work fine now, I'll go ahead and close this. thank you @lesnitsky for the support.