📦flutter localstorage for ios/android/desktop/web

Overview

Localstorage

Simple json file-based storage for flutter

lesnitsky.dev GitHub stars Twitter Follow

Installation

Add dependency to pubspec.yaml

dependencies:
  ...
  localstorage: ^4.0.0+1

Run in your terminal

flutter packages get

Example

class SomeWidget extends StatelessWidget {
  final LocalStorage storage = new LocalStorage('some_key');

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: storage.ready,
      builder: (BuildContext context, snapshot) {
        if (snapshot.data == true) {
          Map<String, dynamic> data = storage.getItem('key');

          return SomeDataView(data: data);
        } else {
          return SomeLoadingStateWidget();
        }
      },
    );
  }
}

V2 -> v3 migration

V3 doesn't add .json extension to a storage filename, so you need to do this on your own if you need a "migration". If you were using v2 with code like below:

final storage = new LocalStorage('my_data');

v3 equivalent:

final storage = new LocalStorage('my_data.json')

Integration tests

cd ~/flutter_localstorage/test
flutter packages get
flutter drive --target=lib/main.dart

License

MIT

lesnitsky.dev GitHub stars Twitter Follow

Comments
  • Error on init - Unexpected end of input (at character 1) ^

    Error on init - Unexpected end of input (at character 1) ^

    99/100 times the code we use to start our app up, everything works. Every once in a great while- we see this error and the app hangs.

    Non-fatal Exception: FormatException: Unexpected end of input (at character 1) ^
    thrown null
    

    Here is a look at the stack I am seeing in crashlytics. Screen Shot 2020-05-21 at 5 24 08 PM

    The code I run to initiate this is await _storage.ready

    I threw up a PR but it is more investigative in nature. I have noticed json.encode("") or json.encode(null) does throw the error Unexpected end of input (at character 1) ^

    opened by cookseym 38
  • Data doesn't persist in latest version, does in 2.0.0 (android)

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

    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.

    opened by nicoroy2561 20
  • NoSuchMethodError: The method 'lock' was called on null.

    NoSuchMethodError: The method 'lock' was called on null.

    This issue again on version ^3.0.6

    I/flutter (20717): NoSuchMethodError: The method 'lock' was called on null. I/flutter (20717): Receiver: null I/flutter (20717): Tried calling: lock()

    Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 1.22.4, on Mac OS X 10.14.6 18G103 darwin-x64, locale zh-Hans-MY)

    [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) [✓] Xcode - develop for iOS and macOS (Xcode 11.3.1) [✓] Android Studio (version 4.0) [✓] Connected device (1 available)

    • No issues found!

    opened by Stevensie95 17
  • Unhandled Exception: FileSystemException: An async operation is currently pending

    Unhandled Exception: FileSystemException: An async operation is currently pending

    I updated the localstorage version to ^3.0.6+9 but I get the following exception

    [VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: FileSystemException: An async operation is currently pending, path = '/Users/username/Library/Developer/CoreSimulator/Devices/5C337305-95CC-4BB3-926F-B607E154A1A9/data/Containers/Data/Application/CD793806-AF33-4755-B7E2-D110B346032A/Documents/filename.json'

    This is the output of Flutter doctor :

    flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel unknown, v1.17.5, on macOS 11.1 20C69, locale en-KW)

    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) [✓] Xcode - develop for iOS and macOS (Xcode 12.2) [✓] Android Studio (version 4.0) [✓] VS Code (version 1.52.1) [✓] Connected device (1 available)

    • No issues found!

    If this exception is not caused by this library, Kindly let me know.

    opened by nilevars 16
  • No loaded items after updating to 3.0

    No loaded items after updating to 3.0

    Thanks for this package, I really like localstorage and never had issues before.

    After updating to 3.0.0+2 my app did not load any items with the following code:

    final LocalStorage storage = LocalStorage('filename');

      Widget build(BuildContext context) => FutureBuilder(
            future: storage.ready,
            builder: (BuildContext context, snapshot) {
              if (snapshot.hasData) {
                storage.getItem('listname');
                ...
    

    Does loading have to be async now - and how do I implement it?

    opened by nohli 11
  • Where this plugin store the data in the phone storage?

    Where this plugin store the data in the phone storage?

    Hi, I have gone through this plugin and also I have used the localstorage for my application to store the sensitive data. You have just mentioned the Simple JSON file-based storage for flutter in the readme file. I have some doubts and I suggest you update your readme file with the answer to the below questions.

    1. Can you please add some more information that where this plugin store the data inside the phone(Android and iOS)?
    2. The stored data for the application is accessible for the user or not?
    3. Are you using any encryption algorithm to store the data?
    opened by DhavalRKansara 8
  • Data don't persist after closing app

    Data don't persist after closing app

    I am using the latest version of the package , everything works perfectly until I close the app or use hot reload, the data vanishes .I've tried several solutions (calling storage.ready in a future builder) etc But still no persistent data , this my code , inspired from the example provided with the package

      return FutureBuilder(
            future: storage.ready,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
              List<Qrqc>? list = [];
              var liststorage;
              if (!initialized) {
                liststorage = storage.getItem('todos');
                if (liststorage != null) {
                  list = liststorage.cast<Qrqc>();
                }
    
                initialized = true;
              }
    
              return ListView.builder(
                  physics: const BouncingScrollPhysics(),
                  shrinkWrap: true,
                  itemCount: list!.length,
                  itemBuilder: (BuildContext context, int index) {
                    return Column(
                      children: [
                        ConditionalBuilder(
                            condition: list![index].status == 'INIT',
                            builder: (context) => QrqcBody(
                                  child: QrqcCard(
                                      child: QrqcCardBody(
                                    color: Colors.orange,
                                    text: list![index].status,
                                    leading: QrqcCardLeaing(
                                        imgPath: "assets/icons/unknown.png"),
                                    trailing: QrqcCardtrailing(
                                      text: list[index].progress.toString(),
                                      percent: list[index].progress.toString(),
                                    ),
                                    title: list[index].id.toString(),
                                    subtitle: list[index].title,
                                    chlidren: [
                                      QrqcDetailsCardFirstRow(
                                        product:
                                            list[index].productName ?? 'no product',
                                        role: list[index].role ?? "no role",
                                      ),
                                      const SizedBox(height: 10),
                                      QrqcDetailsCardSecondRow(
                                        perim:
                                            list[index].perimeterName ?? "no perim",
                                        date: convertDateTimeDisplay(
                                            list[index].createdAt!),
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  )),
                                ),
                            fallback: null),
                        ConditionalBuilder(
                            condition: list[index].status == 'SUBMITTED',
                            builder: (context) => QrqcBody(
                                  child: QrqcCard(
                                      child: QrqcCardBody(
                                    color: Colors.blue,
                                    text: 'SUB',
                                    leading: QrqcCardLeaing(
                                        imgPath: "assets/icons/unknown.png"),
                                    trailing: QrqcCardtrailing(
                                      text: list![index].progress.toString(),
                                      percent: list[index].progress.toString(),
                                    ),
                                    title: list[index].id.toString(),
                                    subtitle: list[index].title,
                                    chlidren: [
                                      QrqcDetailsCardFirstRow(
                                        product:
                                            list[index].productName ?? 'no product',
                                        role: list[index].role ?? "no role",
                                      ),
                                      const SizedBox(height: 10),
                                      QrqcDetailsCardSecondRow(
                                        perim:
                                            list[index].perimeterName ?? "no perim",
                                        date: convertDateTimeDisplay(
                                            list[index].createdAt!),
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  )),
                                ),
                            fallback: null),
                        ConditionalBuilder(
                            condition: list[index].status == 'VALIDATED',
                            builder: (context) => QrqcBody(
                                  child: QrqcCard(
                                      child: QrqcCardBody(
                                    color: Colors.green,
                                    text: 'VALID',
                                    leading: QrqcCardLeaing(
                                        imgPath: "assets/icons/unknown.png"),
                                    trailing: QrqcCardtrailing(
                                      text: list![index].progress.toString(),
                                      percent: list[index].progress.toString(),
                                    ),
                                    title: list[index].id.toString(),
                                    subtitle: list[index].title,
                                    chlidren: [
                                      QrqcDetailsCardFirstRow(
                                        product: 'fromoff',
                                        role: list[index].role ?? "no role",
                                      ),
                                      const SizedBox(height: 10),
                                      QrqcDetailsCardSecondRow(
                                        perim:
                                            list[index].perimeterName ?? "no perim",
                                        date: convertDateTimeDisplay(
                                            list[index].createdAt!),
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  )),
                                ),
                            fallback: null),
                        ConditionalBuilder(
                            condition: list[index].status == 'ESCALATED',
                            builder: (context) => QrqcBody(
                                  child: QrqcCard(
                                      child: QrqcCardBody(
                                    color: Colors.red,
                                    text: 'ESCAL',
                                    leading: QrqcCardLeaing(
                                        imgPath: "assets/icons/unknown.png"),
                                    trailing: QrqcCardtrailing(
                                      text: list![index].progress.toString(),
                                      percent: list[index].progress.toString(),
                                    ),
                                    title: list[index].id.toString(),
                                    subtitle: list[index].title,
                                    chlidren: [
                                      QrqcDetailsCardFirstRow(
                                        product:
                                            list[index].productName ?? 'no product',
                                        role: list[index].role ?? "no role",
                                      ),
                                      const SizedBox(height: 10),
                                      QrqcDetailsCardSecondRow(
                                        perim:
                                            list[index].perimeterName ?? "no perim",
                                        date: convertDateTimeDisplay(
                                            list[index].createdAt!),
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  )),
                                ),
                            fallback: null)
                      ],
                    );
                  });
            });
    
    

    How can I fix the issue for I've been stuck for a while now . Thank you so much for considering helping me

    opened by talbiislam96 6
  • await storage.getItem('userObj') always return null value

    await storage.getItem('userObj') always return null value

    I'm using the below code in my flutter mobile app. It does not persist in storage value. When I close and reopen the mobile app it's automatically cleared.

    My Code: Future isLoggedIn() async { bool flag = false;

    await storage.ready;
    print("storage.ready=======================>");
    print(await storage.getItem('userObj'));
    
    print("isLoggedIn---------------------------test");
    print(await storage.getItem('testingLocal'));
    if (await storage.getItem('userObj') != null && await storage.getItem('userObj') != "") {
      flag = true;
    }
    
    return flag;
    

    }

    opened by saravanans55 6
  • Desktop support - Unsupported Error but was able to return data from getItem?

    Desktop support - Unsupported Error but was able to return data from getItem?

    Hey there,
    I was just trying this out today and got the error of:

    Exception has occurred.
    PlatformNotSupportedError
    

    At the same time, though, I was running this code below: (Don't mind the extra stuff, I was trying to test out FireStoreClient as well to see what kind of data things contained)

    		  final fbClient = FirestoreClient(data.name, data.password, fbApp); 
              _storage.setItem('user', '${fbClient?.token}'); // --------------------------- Error occurred on this line but... 
              _storage.setItem('userToken', '${fbClient?.token?.accessToken}');
    
              var user = 'user';
              var token = 'userToken';
              log.i('From LocalStorage: user: ${_storage.getItem(user)}');
              log.i('From LocalStorage: token: ${_storage.getItem(token)}'); // ------------ Data was returned here as expected?
    

    So, I am not sure if there actually was an issue, or if it works because it returned the data?

    If it doesn't support Windows, is it possible, or worth the effort to somehow use a 3rd party path library along with this? I saw that this one (https://github.com/dart-lang/path) says it has solid support for Windows/Mac/Linux. I am quite new to Dart/Flutter, though (but with a C#/Go background, so picking this up was pretty easy) so I am unfortunately not quite sure if libraries that do not specifically say they are for Flutter will work with it as they should.

    (Though, now looking back through that Path repo, it looks like it might now actually allow access to the system, and may only allow you to deal with the path as a string, so that may not be helpful, or an option to begin with)

    I do see that this says to have a working Windows implementation https://github.com/google/flutter-desktop-embedding/tree/master/plugins/flutter_plugins/path_provider_fde

    Thanks, -MH

    opened by MostHated 6
  • deleteItem exception

    deleteItem exception

    In 3.0.4+7, calling deleteItem() crashes in flush() if there is no file (nothing has been written yet).

    flutter: NoSuchMethodError: The method 'lock' was called on null. Receiver: null Tried calling: lock() flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5) #1 DirUtils.flush (package:localstorage/src/directory/io.dart:46:25) #2 LocalStorage._flush (package:localstorage/localstorage.dart:103:18) #3 LocalStorage.deleteItem (package:localstorage/localstorage.dart:92:12)

    opened by doc-rj-celltrak 5
  • Inconsistent Return Format

    Inconsistent Return Format

    When I store an object, let's call it MyObject, which is serializable to JSON, using storage.setItem(key, _myObject) then a few seconds later I retrieve it using storage.getItem(key), I get an instance of MyObject back. When I then close the app and reopen it, where I do storage.getItem(key) I get back the JSON Map<String, dynamic> instead of the Object. The return should either always be JSON, or should require a class parameter so that it can always be the Object class passed in.

    opened by waltmoorhouse 5
  • it doesn't persist the data in flutter web even if i don't close the browser.

    it doesn't persist the data in flutter web even if i don't close the browser.

    I'm saving a variable that I need to access even if the user accesses the web application another day. but the saved variable is not persisting.

    I can retrieve a saved variable if I don't rebuild the application, but when I rebuild the data no longer exists

    opened by MarceloDiefenbach 0
  • Unhandled Exception: FileSystemException: File closed

    Unhandled Exception: FileSystemException: File closed

    I want to use LocalStorage with different files (keys). Each of the files is opened with LocaleStorage('my_file.ext'). I always open only one file, there are not multiple files open at the same time.

    When working on Windows, I have to call the dispose() method to close a file before opening another. This is necessary to release the file handle. This works as expected, calling dispose() before opening another file will release the file handle. If dispose() is not called, the file cannot be edited or deleted until the app is closed.

    When opening the same file again, LocalStorage uses the file instance stored in _cache map. As the file handler has been disposed, the following exception is thrown:

    Unhandled Exception: FileSystemException: File closed, path = '...'
    

    To make this work, it is necessary to remove the instance from _cache, when calling dispose(). Otherwise it's not possible to read or write the same file later. This is also a problem when you handle files with the same name but in different paths.

    opened by mixable 0
  • I cant find the file i created in the app folder

    I cant find the file i created in the app folder

    I stored a file with your flutter SDK and it worked as expected. But now I'm trying to get this file from a native app. And somehow I cant find the file, even if my app has the same unique app name and a higher version number.

    Where does this Package store it's files?

    Thank you very much!

    opened by jwiemann 0
  • Quota

    Quota

    What is the quota? Is it editable?

    DOMException: Failed to execute 'setItem' on 'Storage': Setting the value of 'asdf' exceeded the quota. at Storage.[_setItem] (http://localhost:56654/dart_sdk.js:100499:27) at Storage.[dartx._set] (http://localhost:56654/dart_sdk.js:100437:25) at Storage.update (http://localhost:56654/dart_sdk.js:23149:22) at web.DirUtils.new._writeToStorage (http://localhost:56654/packages/localstorage/src/directory/web.dart.lib.js:121:35) at _writeToStorage.next () at runBody (http://localhost:56654/dart_sdk.js:40590:34) at Object._async [as async] (http://localhost:56654/dart_sdk.js:40621:7) at web.DirUtils.new.[_writeToStorage] (http://localhost:56654/packages/localstorage/src/directory/web.dart.lib.js:118:20) at web.DirUtils.new.flush (http://localhost:56654/packages/localstorage/src/directory/web.dart.lib.js:88:35) at localstorage.LocalStorage._internal._flush (http://localhost:56654/packages/localstorage/localstorage.dart.lib.js:129:28) at _flush.next () at runBody (http://localhost:56654/dart_sdk.js:40590:34) at Object._async [as async] (http://localhost:56654/dart_sdk.js:40621:7) at localstorage.LocalStorage._internal.[_flush] (http://localhost:56654/packages/localstorage/localstorage.dart.lib.js:127:20) at localstorage.LocalStorage._internal.setItem (http://localhost:56654/packages/localstorage/localstorage.dart.lib.js:111:28) at setItem.next () at http://localhost:56654/dart_sdk.js:40571:33 at _RootZone.runUnary (http://localhost:56654/dart_sdk.js:40441:59) at _FutureListener.thenAwait.handleValue (http://localhost:56654/dart_sdk.js:35363:29) at handleValueCallback (http://localhost:56654/dart_sdk.js:35931:49) at Function._propagateToListeners (http://localhost:56654/dart_sdk.js:35969:17) at _Future.new.[_completeWithValue] (http://localhost:56654/dart_sdk.js:35817:23) at async._AsyncCallbackEntry.new.callback (http://localhost:56654/dart_sdk.js:35838:35) at Object._microtaskLoop (http://localhost:56654/dart_sdk.js:40708:13) at _startMicrotaskLoop (http://localhost:56654/dart_sdk.js:40714:13) at http://localhost:56654/dart_sdk.js:36191:9

    opened by glennmichaelmejias 0
  • Localstorage ready not gets called when using flutter_test

    Localstorage ready not gets called when using flutter_test

    Hello together i am trying using flutter_test. But with localstorage only my first localstorage.ready callback gets called. Here some snippets of my code

    final LocalStorage accountStorage = new LocalStorage('account');
    final LocalStorage introStorage = new LocalStorage('intro');
    final LocalStorage settingsStorage = new LocalStorage('settings');
    
    @override
      void initState() {
        super.initState();
        WidgetsBinding.instance!.addPostFrameCallback((_) => {
              setState(() {
                accountStorage.ready.then((value) => {_setStorageReady()});
                introStorage.ready.then((value) => {_setIntroStorageReady()});
                settingsStorage.ready.then((value) =>  {print("Settingstorage is ready")});
              })
            });
    }
    

    So when i run this code normally it works fine but with flutter_test only the first callback _setStorageReady() gets called. introStorage and settingsStorage never get that callback.

    opened by Y0ngg4n 0
Owner
Andrei Lesnitsky
Open Source Software Engineer @invertase
Andrei Lesnitsky
Simple tool to open WhatsApp chat without saving the number, developed using Google's Flutter Framework. for Android/ IOS/ Desktop/ Web

OpenWp Simple tool to open WhatsApp chat without saving the number Explore the docs » View Demo · Report Bug · Request Feature Table of Contents About

Swarup Bhanja Chowdhury 15 Nov 1, 2022
Build different UIs for Android, iOS, Web, Desktop, Wear, TV etc without the if/else checks in your widgets.

platform_widget_mixin Plugin to decouple widgets based on various platform properties. Features Build different UIs for Android, iOS, Web, Desktop, We

Rahul Kumar 6 Nov 17, 2022
Trying out Flutter for desktop Web app development as an alternative to SPA frameworks (such as React and Angular) by recreating one of the pages of an existing CV Management web app

HTML Renderer Demo CanvasKit Renderer Demo Reddit discussion This repo contains a PoC of using Flutter as a traditional SPA framework for creating a d

Maxim Saplin 20 Oct 11, 2022
Flathub-desktop - Unofficial Desktop Client for Flathub

Flathub Desktop Unofficial Desktop Client for Flathub How to build and run: You

Jean3219 2 Sep 19, 2022
WooCommerce App template that uses Flutter. Integrated to work with WooCommerce stores, connect and create an IOS and Android app from Flutter for IOS and Android

WooCommerce App: Label StoreMax Label StoreMax - v5.3.1 Official WooSignal WooCommerce App About Label StoreMax Label StoreMax is an App Template for

WooSignal 314 Jan 9, 2023
A Flutter application running on mobile, web and desktop. Stay tuned to see who will win the stars race!

The live stars race Access this project running at jhbitencourt.github.io/stars-race An app running on mobile, web and desktop. How long do you think

null 28 Jul 20, 2022
WebRTC plugin for Flutter Mobile/Desktop/Web

Flutter-WebRTC WebRTC plugin for Flutter Mobile/Desktop/Web Sponsored with ?? by Enterprise Grade APIs for Feeds & Chat. Try the Flutter Chat tutorial

Flutter WebRTC 3.4k Dec 31, 2022
Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern.

Karee Another way to build Flutter applications for mobile, web and desktop using the powerful of MVC Design Pattern. + = About Karee Karee is a frame

@LeCode 44 Sep 29, 2022
Just collection of UI designs build with flutter. Can run on any mobile, web & desktop.

Flutter UI Designs True cross platform app runs on web, mobile & desktop Download Requirements to run locally Flutter stable v2.0.0+ Dart VM version:

Hamza Iqbal 222 Dec 28, 2022
Cross Platform app in Flutter with Firebase Auth and Firestore. Available for Mobile,Web,Desktop

NavokiNotes Navoki Notes, a note app app, will sync data to cloud and on all devices. We have application for Android, iOS, Web App, PWA, Windows, mac

shivam srivastava 93 Dec 27, 2022
Shortcuts and actions - Spice up your Flutter Desktop/Web apps with Shortcuts and Actions

Spice up your Flutter Desktop/Web apps with Shortcuts and Actions A desktop/web

Waleed Arshad 12 Nov 20, 2022
tabler admin panel in flutter web/desktop

fabler A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this i

Milad 1 Dec 14, 2022
Example implementation of Responsive Screen for Mobile, Tablet, Web, and Desktop in Flutter

flutter_responsive A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you start

R. Rifa Fauzi Komara 7 Oct 12, 2022
A portable canvas that can work in many platforms (Flutter, Web, Desktop, in-memory Image).

pcanvas A portable canvas that can work in many platforms (Flutter, Web, Desktop, in-memory Image). Motivation Canvas operations can be highly depende

Graciliano Monteiro Passos 3 Dec 8, 2022
Flutterweb-spotify - Interfaz Clone de Spotify Web-Desktop

Spotify UI Clone Stack Tecnologies Flutter Web & Provider Site Web https://spoti

Efrain May 0 Jan 22, 2022
Horizontal list - A horizontal list widget to use in mainly for web or desktop application

horizontal_list A horizontal list widget with buttons next and previous. You can

Daniel 2 Feb 2, 2022
Flet enables developers to easily build realtime web, mobile and desktop apps in Python. No frontend experience required.

Flet Flet is a framework that enables you to easily build realtime web, mobile and desktop apps in your favorite language and securely share them with

Flet 3.6k Jan 9, 2023
Free game catalogue of desktop & web.

GGame Sebuah app yang menampilkan dan merekomendasi list game - game gratis dari berbagai platform yang bisa dicoba ketika jenuh. Library yang digunak

Rifqi Mufidianto 1 May 23, 2022