I have a SQLite .db file that I want to access through sqflite on Flutter. Where in the Flutter project am I supposed to put it so that I can access it both on Android and iOS? How do I make sure that it's shipped with the apk? All examples that I found assume that the db needs to be created from scratch at the first launch.
You can put the db file in your assets folder and declare it in your pubspec.yaml. On startup you can write it out to disk and then use that path with your connection string to connect the db.
You can read from assets using
var dbContent =
await rootBundle.load('assets/database/mydb.db');
Then write it out to your file system and go from there.
I've found that this problem is related to:
https://stackoverflow.com/a/51387985/3902715
Credits to R. C. Howell
Related
I currently have a Ionic Cordova App in the Playstore that uses the cordova-sqlite-storage plugin. Now I want to switch to Capacitor. Unfortunately I cannot use the storage plugin anymore with Cordova and need to switch to the storage plugin of Capacitor. This would work fine, but the Capacitor Plugin capacitor-data-storage-sqlite automatically adds SQLite.db to the database name.
For example my db file is appDb and if I try to use it with the capacitor plugin using appDb as Name, the plugin trys to use the file appDbSQLite.db and the db schema is also different.
So now I thought, ok I read my old sqlite file with sql querys and then write the values to the capacitor store. Now the problem is, that also the sqlite capacitor plugin #capacitor-community/sqlite appends SQLite.db to the filename, so I am not able to read the values from my appDb file.
Now I thougt, ok I copy my appDb file to appDbSQLite.db, to read the values, with sql queries, but unfortunately, I am not able in any way to copy the database file with the capacitor Filesystem api. I always get the error, that the file does not exist. My appDb file is in the database folder of the app.
Has anybody experienced similar issues, or can tell me, how to copy the database file with capacitor?
I highly appreciate any help with this =)
i made a flutter app which creates then uses an sqlite db.
To share my app, i used to upload the apk file in google drive, but everytime it is downloaded then installed on a phone, the db is empty.
I want to share the app with the db filled, but i don't know how to do this.
Any help please ?
When your users run app at first time, their database is empty. Your problem can be solved by two ways:
Create entities in database (data that you sharing) at database initialization.
Create a backup feature that provides possibility to import database from the user's storage (just replace db file in app's internal folder by db file from external storage (Downloads folder for example)).
As the question in the title says.
My database file could be pretty large so I don't want to make copies of it unnecessarily and I certainly don't want to build it in situ.
If the db file is a flutter asset, is there a way for sqlite to access it directly?
I've seen suggestions that I should copy the raw data of the asset into a file and then access it but that is a waste of storage. Or can I then delete the asset?
Is there a simple way of deploying the database as something other than an asset, ie as a raw file?
iOS (and, I think, Android?) will require you to copy the file into the app's working directory first. This is standard practice, and it's part of working within a protected file system. If somehow it's a deal killer to have copies in both your app bundle (consider this the pristine "master") and app documents folder (the "working copy"), I suppose you could also download it from a server on initial app launch, but... time is money.
It's truly not that big a deal, though. To do so, ensure the file in included in the app bundle via your pubspec.yaml file:
flutter:
assets:
- assets/stored_data.db
Then, before opening the database, copy it from the app bundle to your documents directory:
Edit: The following apparently fails to copy large files; see iKK's comment below if you experience such issues, as it looks like he's found a native solution. For smaller files, however, this should work fine.
// Create a new file within your document directory (Probably want to check whether it already exists first...)
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "working_data.db");
ByteData data = await rootBundle.load(join("assets", "stored_data.db"));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
Now that you have the database within your app's document directory, you should be able to open it from the path. If you're using the tekartik/sqflite package (which is where I originally got these instructions), for instance, you can simply:
Database db = await openDatabase(path); // Opens SQL database, working_data.db
There's no reason (or ability) to delete the pristine copy from the app bundle (which would alter the original binary -- a huge nono). Eventually, the OS itself may end up offloading such dreck to a cloud server or other memory-management service, but that's for the platform to decide.
I'm posting this to assist users who will be encountering the same thing I did when trying to locate a sqlite database being used on the iOS simulator when using Appcelerator.
xCode Version: 8.3.x
Appcelerator Studio: 4.8.x / SDK: 6.x
Issue/Test Case: I need to test several iterations of loading data from the sqlite database to a remote mySQL server. I want to place an existing sqlite database file in the folder and have the simulator recognize this file so I can use it for testing/development.
Question: Where is the sqlite database stored on the iOS simulator, can I place an existing sqlite database in this folder and have my app recognize it?
Answer: Yes
Steps to achieve:
This is what I did to locate where the simulator/device is looking for
1. Find out where your application is located in the filesystem by adding this code in your index.js (or another file of your choosing).
Ti.API.info("app directory: " + Ti.Filesystem.applicationDataDirectory);
This will give you the long filesystem directory location:
/Users/[username]/Library/Developer/CoreSimulator/Devices/96662E38-C659-4568-B53F-C32DC6B2B73D/data/Containers/Data/Application/96662E38-C659-4568-B53F-C32AB6B2C03D /Documents/
2. This was almost the correct location but the sqlite database is actually stored in the following location:
/Users/[username]/Library/Developer/CoreSimulator/Devices/96662E38-C659-4568-B53F-C32DC6B2B73D/data/Containers/Data/Application/96662E38-C659-4568-B53F-C32AB6B2C03D /Library/Private Documents/[filename].sql
3. You can use this location to put an existing sqlite database file and execute sql statements against it.
4. I'm sure you could reference another directory in your app but I was looking for the default storage directory since my app uses this location.
Hope this helps someone, as I was looking for this specific functionality for testing/development.
Happy Coding!
An easy way to get the database included is to simply add it to the resources folder, or a sub folder in the resources directory. Then you simply call the Ti.Database.install() method. This will copy the database into the simulator location you found. The upside with this method is that you don't have find the location for each iOS simulator (i.e. iPhone 5, 6, 6 plus, 7...).
I do use your method when I need to query the database externally with SQLite manager or another such program.
You can read more here http://docs.appcelerator.com/platform/latest/#!/guide/Working_with_a_SQLite_Database
I have an existing sqlite db file(Windows phone 8) which I use only for reading tables (Not Inserting anything)
the sqlite file gets copied to ApplicationData.Current.LocalFolder so db file are at both location.My problem is how to give security to the db file so that it should not be copied by any other user(hacker) or any application that access Local folder or Installation folder.
Is there any solution db file be copy protected without encrpting or any other simpler solution.
I am not sure if any other app can access that DB however you can always create a password protected SQLlite DB. Take a look here for more info.