Save Cordova database to Dropbox

How to save your database to Dropbox (and how to restore it) from within a Cordova application – Android only (part 2)

Wellcome to the second part of my tutorial about how to save your database to Dropbox from within a Cordova mobile application. Here we’ll see how to manage backup and restore of a database using a helpful plugin: SQLite Porter by Dave Alden. The plugin is fantastic, it works great and let me share with you I’m proud indeed to have joined the contributors group fixing a small bug which prevented to successfully use exportDbToSql() and importDbFromSql().

SQLite Porter plugin

SQLite Porter allow you to export and import a database using just a few lines of code. You can export the database to a json file or to a sql file using exportDbToJson() and exportDbToSql() functions. To import a databse you can use the correspondent functions importJsonToDb() and importSqlToDb().

So, open your command prompt o your terminal window and navigate to your project root, then type:

That’s all: the plugin is ready for us.

Managing files: cordova-plugin-file

But files must be managed: we have to create them and their directories, we must be able to read their content and to write content to files. To do so we’re going to install an important cordova plugin which is used to read and write files within the host OS. You should still have your terminal (or command prompt) open in your project root directory (if not, then open it and go there). Type this:

Exporting the database to a backup file

All right! We can finally type some code, now! First we’ll write the function which actually exports our database and writes down a mysql dump file: put the follwing code before the jQuery main function.

If you want to go deeper in file-system API, I suggest to read, besides the mandatory Cordova man page, two great articles https://www.html5rocks.com/en/tutorials/file/filesystem/ and https://www.neontribe.co.uk/cordova-file-plugin-examples/.

Let’s analyze this code line by line. As you can see, the function it is divided in 2 sections: the former is the callback function, the latetr is the SQLite Porter function which actually exports the database and then calls the callback function. This second part is quite simple and we have nothing interesting to note about it. But the calback function allows us to check how Cordova manages the access to and the manipulation of files and directories.

Code anatomy

First we find the resolveLocalFileSystemURL() (see here: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html#where-to-store-files). As from version 1.2, for each important file-system directory is provided an URL:

Each URL is in the form file:///path/to/spot/, and can be converted to a DirectoryEntry using window.resolveLocalFileSystemURL().

We pass this function the parameter cordova.file.dataDirectory: we’re telling Cordova we want to store our file in the Internal Storage. This is the recommended to store any persistent application data because it is accessible exclusively by our application. We’ll check this later, when we’ll have already created our backup file. So cordova.file.dataDirectory is equal to the path /sdcardAndroid/data/com.codingfix.dropboxTest/ and it is converted to an object of type DirectoryEntry we have called dirEntry. dirEntry object is returned by the callback anonymous function we use in resolveLocalFileSystemURL(): window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dirEntry) {

Let’s examine our callback function: we immediately see we use a method of the object DirectoryEntry, the method getDirectory() and we pass it 2 parameters and another anonymous callback function: dirEntry.getDirectory('/dropboxTestBackup', {create: true}, function (dirEntry) {

The method getDirectory() accept four parameters (here we only use three): a string which represents the relative path of a directory, a boolean value which set if the directory must be created if not found and two callback functions for success and error (this one is not used in our example). In other words, our app is telling Android to look for directory /sdcardAndroid/data/com.codingfix.dropboxTest/ and to create in that directory a new directory called dropboxTestBackup where we’ll store our backup files.

The callback function uses the new object of type DirectoryEntry created by the method getDirectory() to create the backup file itself: dirEntry.getFile('dropboxTestBackup.sql', {create: true}, function (fileEntry) { . This time we use the method getFile() which is almost identical to the method getDirectory() used above with the obvious difference that it creates a file instead of a directory and returns a reference to that file. We use the object fileEntry in the last callback function where we alert the application user that the file has been successfully created and we write our data to the file:

Hey, what’s that?!? We never talked about a writeFile() function!!! – I hear you say. Don’t worry, guys: we’re going to look at that right now 🙂

Writing files

Yes, we have to write data to a file, we knew that, isn’t it? So look at this function (and keep you ready to know about reading files, later in this article):

The function is quite simple: it just accept 2 params, the file object which points to the phisical file created in our file system and the data to write to the file: writeFile(fileEntry, sql); This function then uses internally the readFile() function to read the just created file and ouput its content in the console. As we have noticed above, storing the file in the Internal storage (as it is recommended for security reasons) doesn’t allow us to find this file using any third party application. Nor your pre-installed file manager nor a third-party one can see this file (dropboxTestBackup.sql) nor the directory where the file is created in (/dropboxTestBackup), so this is the only one way we have to check if everything went fine.

 

If you want to create a public file, accessible by your Android file manager or even by your computer when your Android device is connected vis a USB cable, you have to use externalDataDirectory instead of dataDirectory, but this expose your files to be accessed by third party software. So feel free to use externalDataDirectory while in development, to make easier to debug your app, but keep in mind to replace it with dataDirectory when in production.

Okay. So far we have learnt how to export our database in a sql format and how to write these data ta a file within our file system. Now we have to import these data into our database (if something inadvertently had wiped our data).

Importing a backup file into our database

So now we want to perform the opposite operation, read data from a file and use them to restore our application database. The code is easily understandable considering what we have learnt before.

We set first the path to our backup file, then we use resolveLocalFileSystemURL() to get the fileEntry to read file’s content and to use them in callback function onloadend() as parameter to give to cordova.plugins.sqlitePorter.importSqlToDb(). Once the file is loaded, we alert the user and call our two functions to fill out our controls. Voilà, les jeux sont faits!

Make buttons to work!

Do you remember the code we had written in our index.js file to attach the event handler to our buttons? It looked this way:

Now we have to add a call to exportBackup() and importBackup() functions in order to make this block of code look slightly different:

I show you how the whole index.js file should look so far:

 

Now we can export our database to a local file and if it is necessary, restore it from the backup file. Just run the app, and follow these steps to test the app:

  1. Tap Create database to create the database (if you didn’t do it yet)
  2. Export it tapping Export database button
  3. Now tap Empty database button to drop out all your data
  4. and then tap Import database button to see your data live again!

Great, isn’t it?

But we want to be sure our user can get back his data even if he has uninstalled our application in a moment of mental disorder and then, once he has returned to reason, he has reinstalled it. So we need to offer him the option to save his backup file to some external host. Do you guess? Yeah, Dropbox! And this will be the argument of the next, final chapter of this tutorial.

 


 

Leave a Reply

Your email address will not be published. Required fields are marked *