lesnitsky / flutter_localstorage

📦 LocalStorage for Flutter
MIT License
301 stars 60 forks source link

Data don't persist after closing app #86

Closed talbiislam96 closed 2 years ago

talbiislam96 commented 2 years ago

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

popiosifcristian commented 2 years ago

In my case, I've created a singleton local storage service, declared main function async and await for storage.ready then run the app. I have no issues of data not persisting on hot reload/restarting the app and also in this scenario I don't need future builders everywhere I need to get an item from the storage. Anyway in your implementation, inside of future builders, you should check the connection state->error->data rather than just the data of the snapshot.

cookseym commented 2 years ago

@talbiislam96 Try adding await Future.delayed(Duration(seconds:4)); as the first line in your builder, and make sure it is async.

(This is to help bubble up an issue that I suspect the .ready future has.)

pselvaraj-uas commented 2 years ago

In my case, I've created a singleton local storage service, declared main function async and await for storage.ready then run the app. I have no issues of data not persisting on hot reload/restarting the app and also in this scenario I don't need future builders everywhere I need to get an item from the storage. Anyway in your implementation, inside of future builders, you should check the connection state->error->data rather than just the data of the snapshot.

Would you please post your singleton localstorage access class? Thanks!

celinaT commented 2 years ago

There is an issue with the map used for caching. I've spent several hours with the issue myself and the only way to solve it, was to implement it from scratch. I've also tried out everything which was suggested by the app developer, but nothing worked. Long story short, in case you are opening and closing the app, you can forget this library

garyodonoghue commented 2 years ago

the trick for me was to await storage.ready() after initialisation. So have

final LocalStorage storage = new LocalStorage('blah.json'); await storage.ready;

After that, writing and readying was working fine. I would do a quick check outside of future builders etc, that this works as expected for you.

In your example above, you're not actually checking the value of the future's response, maybe you should show the spinner until it returns true? e.g. something like below?

if (snapshot.data != null && snapshot.data == true) { // local storage is definitely ready now }

lesnitsky commented 2 years ago

For future readers:

make sure to

await storage.setItem('foo', 'bar');
^^^^ THIS IS IMPROTANT