1

I have this Sqlite database file inside the device's 'Documents' folder named backup.db. Now I have written function that should be able to import that database, but I am getting some weird asynchronous errors, not sure what I am doing wrong here, might need to add something. Here's the code for importing the existing file:

    class DbHelper {
  Future initDb() async {
    final dbPath = await ExtStorage.getExternalStoragePublicDirectory(
        ExtStorage.DIRECTORY_DOCUMENTS);
    final path = join(dbPath, '/backup.db');
    final exist = await databaseExists(path);
    if (exist) {
      print('db imported');
      await openDatabase(path);
    } else {
      print('creating copy of database');
      //try {
        //await Directory(dirname(path)).create(recursive: true);
      //} catch (_) {}
      //ByteData data = await rootBundle.load(join(dbPath, '/backup.db'));
      //List<int> bytes =
         // data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
     // await File(path).writeAsBytes(bytes, flush: true);
    }
    await openDatabase(path);
  }
}

As far as I got, it gets the 'documents' directory, merges the path with backup.db file that already exists in Documents, then it should just import it if it exists. Let me know if there is anything I am doing wrong. I am using the ext_storage library to locate the documents folder and sqlite of course to be able to import the database.

And in another screen I call this function like this:

DbHelper dbHelper = new DbHelper();

onTap: () => dbHelper.initDb(),

Here's the stacktrace:

    [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Unable to load asset: /backup.db
E/flutter (22458): #0      PlatformAssetBundle.load
package:flutter/…/services/asset_bundle.dart:225
E/flutter (22458): <asynchronous suspension>
E/flutter (22458): #1      DbHelper.initDb
package:CWCFlutter/db/import_database.dart:21
E/flutter (22458): <asynchronous suspension>
E/flutter (22458): #2      _FoodListState.build.<anonymous closure>
package:CWCFlutter/food_list.dart:919
E/flutter (22458): #3      GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:183
E/flutter (22458): #4      TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:598
E/flutter (22458): #5      BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:287
E/flutter (22458): #6      BaseTapGestureRecognizer.acceptGesture
package:flutter/…/gestures/tap.dart:259
E/flutter (22458): #7      GestureArenaManager.sweep
package:flutter/…/gestures/arena.dart:157
E/flutter (22458): #8      GestureBinding.handleEvent
package:flutter/…/gestures/binding.dart:362
E/flutter (22458): #9      GestureBinding.dispatchEvent
package:flutter/…/gestures/binding.dart:338
E/flutter (22458): #10     RendererBinding.dispatchEvent
package:flutter/…/rendering/binding.dart:267
E/flutter (22458): #11     GestureBinding._handlePointerEvent
package:flutter/…/gestures/binding.dart:295
E/flutter (22458): #12     GestureBinding._flushPointerEventQueue
package:flutter/…/gestures/binding.dart:240
E/flutter (22458): #13     GestureBinding._handlePointerDataPacket
package:flutter/…/gestures/binding.dart:213
E/flutter (22458): #14     _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter (22458): #15     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (22458): #16     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (22458): #17     _invoke1 (dart:ui/hooks.dart:265:10)
E/flutter (22458): #18     _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)

updated code

  class DbHelper {
  Future<void> initDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String newPath = join(documentsDirectory.path, '/backup.db');
    final exist = await databaseExists(newPath);
    print("This print works.");
    if (!exist) {
      try {
        final dbPath = await ExtStorage.getExternalStoragePublicDirectory(
            ExtStorage.DIRECTORY_DOCUMENTS);
        final path = join(dbPath, '/backup.db');
        File(path).copySync(newPath);
        print("This print doesn't work.");
      } catch (_) {}
    }
  }

  Future<Database> openDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, '/backup.db');

    await initDB();
    Database db = await openDatabase(path);

    return db;
  }
}
4
  • I have tried flutter clean but still getting the same error, mostly asynchronous suspension Commented Jan 23, 2021 at 18:12
  • 1
    Can you add an error to the question? Commented Jan 23, 2021 at 18:14
  • Post your errors StackTrace Commented Jan 23, 2021 at 18:18
  • added StackTrace in original post Commented Jan 23, 2021 at 19:25

1 Answer 1

5
ByteData data = await rootBundle.load(join(dbPath, '/backup.db'));

You are trying to load "/backup.db" from the asset bundle adding dbPath to the key.

You need to add the backup.db to the assets folder if you want to load the database this way.

If you know the location of the .db file and it's not in the assets then why do you need to import it? Just open it.

You can copy the database to another location using File(path).copy(String newPath)

Future<void> initDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String newPath = join(documentsDirectory.path, '/backup.db');
    final exist = await databaseExists(newPath);
    if (!exists) {
        try {
            final dbPath = await ExtStorage.getExternalStoragePublicDirectory(
            ExtStorage.DIRECTORY_DOCUMENTS);
            final path = join(dbPath, '/backup.db');
            File(path).copySync(newPath);
        } catch (_) {}
     }
}

Future<Database> openDB() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, '/backup.db');
    await initDB();
    Database db = await openDatabase(path);
    return db;
}
Sign up to request clarification or add additional context in comments.

9 Comments

Yeah, I figured that out. I know the exact path of the file, it is always here: final dbPath = await ExtStorage.getExternalStoragePublicDirectory( ExtStorage.DIRECTORY_DOCUMENTS); final path = join(dbPath, '/backup.db');
Could you give me the code on how it would work out in my context? I've been trying out to do it this way, but I still get errors, so I'm not sure what I'm doing wrong @Sergey Inshev
@arbiter I've updated the answer with a code snippet. This code will look for the database within the ApplicationDocumentsDirectory. If not found will copy the database from the ExtStorage.DIRECTORY_DOCUMENTS
I appreciate your help, let me see how to link it all up and I'll get back to you asap. Just one more question, how would I initialize this function onTap? I suppose I would call openDB()? @Sergey Inshev
you should call the function with await -> "await openDB()"
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.