Ionic cordova build removes /www directory and implicitly my .db file

Hello,
I am using ionic+cordova+angular for an app. I have a database.db file in /www and by using ionic sqlite copy plugin, i managed to copy the .db file and after that using it with ionic sqlite plugin. All works well when debugging with ionic cordova build android -l --debug.
But when i try just ionic cordova build android for building my apk, it deletes the whole /www file and i loose the .db file. The bad part is that the copy method from ionic sqlite copy plugin only wants that .db file to be in /www, i cannot give a custom reference to the file.
So, is there any way to not have the www/database.db deleted? Or do you have another idea for this issue?

Thanks!

Like node_modules, don’t manually touch anything under www. Under src/assets/ somewhere is the typical place for things like your database file.

You are to place the database in platforms/android/platform_www . This way your database gets bundled whenever you build your app and also copies it to www folder automatically. I hope this helps you. Cheers!!!

Hi, thanks for the message. I managed to solve the issue by having the .db file in /assets and having a rule in angular.json to copy all .db files from /assets into /www when the dir is created at build. But you idea seems better, i didn t knoe that platforms/android/platform_www is integrally copied into /www.
Many thanks and all the best

FWIW, I disagree. It won’t survive platform removal/readdition, and won’t work in CI or automated build environments. You should not need to be manually copying anything: put things in src/assets and they should be incorporated for you.

The problem with just having the .db file in /assets is that the sqlite db copy plugin won’t work, because it checks just /www for the .db . With any other type of file(imgs, fonts etc) i totally agree with you, but if you want to use that plugin, you need to have the .db inside /www. Angular.json has config for copy procedure, copying things from /assets to /www at build, so i just added the rule for copying .db files, alongside images fonts and other resources.

For the issue of platform removal or adding he just need to put the file back in there and it is not everytime you remove platform and add back.

You are welcome @edy1993 glad to be of help

Sorry to All, but I’ve the same problem. I’ve not understood your solution.
Could you explain to me what does it mean platforms/android/platform_www ?
I cannot find that path…

Thank you in advance.
Marco

Hello Miliziano,

My solution(and it works just fine) was:

  1. have your .db file in src/assets
  2. put this rule in your angular.json file:
    {
    “glob”: “**/*.db”,
    “input”: “src/assets”,
    “output”: “./”
    }
    under projects/app/architect/build/options/assets.
    this will copy at buildtime all your .db files from src/assets to /www, where the plugin needs .db file to be.

let me know if this helps you.

Hello edy1993.
Thank you for the answer.
We are on the road… but…

Your snippet runs! Now, the mydatabase.db is into the www folder of Angular/Ionic project…
Now, in the Android project, I find the file into path:
…\project_name\android\app\src\main\assets\public\mydatabase.db

But, again, the this.sqliteDbCopy.copy( ‘mydatabase.db’, 0) doesn’t find in the source path the db file.
The error code is ever 400 with message: D/Cordova: Try Error = www/mydatabase.db

Can you fire another light on this?

Thank you, thank you…

hello,
Sure. this is the complete code from my app which open and use a local database which is copied in /www at runtime by the snippet code you just put in angular.json from the previous message.

database: SQLiteObject;
private databaseReady: BehaviorSubject;

constructor(private storageService : StorageService, private sqlite: SQLite, private platform: Platform, private sqliteDbCopy: SqliteDbCopy) {
this.databaseReady = new BehaviorSubject(false);
this.platform.ready().then(() => {
this.storageService.getStorageSettings(Constants.DATABASE_FILLED).then(result => {
if(result) {
if(result != Constants.YES) {
this.sqliteDbCopy.copy(Constants.DATABASE_NAME, 1).then((res: any) => {
storageService.setStorageSettings(Constants.DATABASE_FILLED, Constants.YES).then(() => {
this.createAndOpenDB();
});
}).catch((error: any) => {
console.error(error)
});
} else {
this.createAndOpenDB();
}
} else {
this.sqliteDbCopy.copy(Constants.DATABASE_NAME, 1).then((res: any) => {
storageService.setStorageSettings(Constants.DATABASE_FILLED, Constants.YES).then(() => {
this.createAndOpenDB();
});
}).catch((error: any) => {
console.error(error)
});
}
});
});
}

createAndOpenDB() {
const options: any = {
name: Constants.DATABASE_NAME,
location: ‘default’,
createFromLocation: 1
};
this.sqlite.create(options).then((db: SQLiteObject) => {
this.database = db;
//this.loadProducts(); <- here you can call your sql methods. i will put an example of this as well below.
this.databaseReady.next(true);
}).catch(e => {
console.log(“error open db”, e);
});
}

getAllProducts() {
return this.database.executeSql(“SELECT * FROM product”, ).then((data) => {
let products = ;
if (data.rows.length > 0) {
for (var i = 0; i < data.rows.length; i++) {
products.push({
id: data.rows.item(i).product_id,
name: data.rows.item(i).product_name
});
}
}
return products;
}, err => {
console.log('Error: ', err);
return [ ];
});
}

PS. as you can see, you will have to use 2 plugins in order to use a local prepopulated database into a cordova-ionic project.

1st step is to copy the .db file from src/assets to /www with that rule from angular.json. (which you already did).
2nd step is to use only once (see my code above with that check on a storage memory app parameter which i called DATABASE_FILLED) the plugin cordova-plugin-dbcopy (link here: https://ionicframework.com/docs/native/sqlite-db-copy ). this plugin will only copy the .db file found in /www into the correct place where a .db file should be for an android/ios app. that’s it with it. I said only once because otherwise you will get an error like “DB ALREADY EXISTS”.
3rd step is to use the plugin cordova-sqlite-storage (link here: https://ionicframework.com/docs/native/sqlite ) to open the database and execute queries and on it.

From my code above, the StorageService is a local service written by me which uses the native storage plugin( link here: https://ionicframework.com/docs/native/native-storage) which holds small amount of key-value info into app’s memory. getStorageSettings()/ setStorageSettings() are methods which set and get values into memory with that plugin.

Please tell me that it works for you. When i developed that, i spent 2-3 days on it cuz i found nothing on the net and i understand your struggle.
All the best

by the way,
my code works only for cordova+ionic.
I tried to make it work on capacitor+ionic, but with no success.
I m not sure if these plugins work for capacitor. it seems that they were not updated to work on capacitor too.

If you are using capacitor, i m afraid i cannot help you.

I use capacitor, I will inform you about my success… or not success !
I found low information; it seems incredible because it’s a so important issue, to have a pre-filled DB on the app…
I appreciated your help. Thank you at the moment.
Marco

an update: I use the same code you are using. I think the problem is on Capacitor…

Debugging into Android I’ve found:

W/System.err: java.io.FileNotFoundException: www/mydatabase.db

when plugin perform a :
myInput = cordova.getActivity().getAssets().open(“www/” + dbName);

the file is in :
…\project_name\android\app\src\main\assets\public\mydatabase.db

I still have to understand that www folder…

cheers

Solved.
Solved!

The www corresponds to public !

myInput = cordova.getActivity().getAssets().open(“www/” + dbName);

becames
myInput = cordova.getActivity().getAssets().open(“public/” + dbName);

and plugin runs on Android with Capacitor on Ionic5,

I change it into my Android project, but I suggest our friends to change it into the gitHub.

I’dont know if there are other differences among android versions…

Thank you to all.
Marco

Hello,
Good job. But how about ios?
All the best

I’m afraid, but one step at time… at the moment…
:grinning_face_with_smiling_eyes:

I hope that the guys of the plugin can apply some changes…

By…

It means open platforms folder then android folder then platform_www folder, now put it the db file inside it.

Using capacitor and got the same problem.
I’m good until copying db file to www/
But I cannot understand the way you solved it.
If you could please help.