How to Backup Your Data Tables in Backendless

In this article, we will show you how to write a service that will backup your application data with a time interval you specify. To do this, we will be using Cloud Code, a JavaScript timer, and the console SDK.

The result of this operation will be an archive with the data of all your tables (or, if you wish, you can modify the service for backing up specific individual tables, geo-points, application settings, etc.).

First, we need to create a simple timer which in the future will call a service for backup.

Open your application in Backendless Console and go to the Business Logic menu on the left. Open the Timers menu and click New Timer. A modal window will appear, as in the screenshot below. You can give any name you wish to the timer, excluding spaces and wild cards. We will call it BackupDataTables. Also in this window, you can set the schedule for calling the timer. We set the value to daily, and repeat every one day.

Now you should see your timer in the list:

Next, go to the Coding tab and load your project:

Open the downloaded project in your preferred code editor. Don’t forget to run npm install to install all the dependencies.

To write the service, we need the Console API. The Console API was originally meant to be internal and not used in any automation. That’s why it was never added to the Client SDKs. This wasn’t a technical decision, but rather a measure to increase the stability of the application. The operations available only with Console API are mostly those changing the database structure or some internal configurations. In our case, we will use the API to export the tables.

Using your most convenient package manager (yarn, npm), install the module backendless-console-sdk.

Now let’s create a file in the services folder. Just call it backup.js, meaning that other backup methods for other data may potentially appear in the service.

The contents of this file will be as follows (see notes in the comments in the code):

const consoleSDK = require('backendless-console-sdk')

class Backup {
  /**
   * @route POST /tables
   * @returns {Promise.<void>}
   */
  async backupDataTables() {
    const { login, password } = this.config // Values provided in console configuring this service after deploy.
    const { appId } = this.request.context // More about invocation context here:
                                           // https://backendless.com/docs/bl-js/bl_invocation_context.html

    // Create api client using `createClient` method of console SDK.
    // It expects server url, which we can take from Backendless SDK’s ‘serverURL’
    const apiClient = consoleSDK.createClient("https://v4api.backendless.com")

    // Because of using console API, it is required to be authorized in order to perform requests.
    // We log in console’s developer. We suggest registering a special developer for this purpose,
    // but you may use your own credentials.
    await apiClient.user.login(login, password)

    // Here we retrieve exported data from console.
    // It will return an object with the following structure:
    // { tables: [{ id, name, related: [...]}, ...], views: [{ id, name, sourceTableIds: [...]}, ...] }
    const exportedData = await apiClient.transfer.getExportedData(appId)
    // map tables ids to send it for starting export of these tables
    const tableIds = exportedData.tables.map(table => table.id)

    // map views ids to send it for starting export of these views
    const viewsIds = exportedData.views.map(view => {
      for (const sourceTableId of view.sourceTableIds) { // we also need to export the tables that the views depend on
        if (!tableIds.includes(sourceTableId)) {
          tableIds.push(sourceTableId)
        }
      }

      return view.id
    })

    const exportPayload = {
      addDataTypes: true,
      appsettings : false, // set true if you'd like to export app settings
      schemaOnly  : false, // set true if you'd like to export tables schema only (without data)
      tables      : tableIds, // list of tables ids
      views       : viewsIds // list of views ids
    }

    // start export
    return apiClient.transfer.startExport(appId, exportPayload)
  }
}

// add service and as a second argument you may pass an array of configuration items
// here we pass login and password fields
Backendless.ServerCode.addService(Backup, [{
  name       : 'login',
  type       : 'string',
  displayName: 'Login',
  required   : true,
  order      : 0
}, {
  name       : 'password',
  type       : 'string',
  displayName: 'Password',
  required   : true,
  order      : 1
}])

Also, make sure you have “Dynamic schema definition” enabled, otherwise you might encounter an error during service deployment. It’s needed to create a new Data Table BlConfigurationItemDescription dynamically. The table stores all the configurations for your API Services. Once it’s done, you can disable “Dynamic schema definition”.

In the timers folder, find your timer and make the following changes:

/**
 * Export data tables and store in Files storage.
 * Executes according to the schedule once per day.
 */
Backendless.ServerCode.addTimer({

  name: 'BackupDataTables',

  startDate: Date.now(),

  frequency: {
    schedule: 'daily',

    repeat: { every: 1 }
  },

  execute() {
    return Backendless.CustomServices.invoke('Backup', 'backupDataTables')
  }
})

Run ‘npm run deploy’ and, once deployed, go to the Console’s Business Logic menu, click on your service and then click Configure Service (gear icon):

The configuration modal will open:

Enter Login and Password and click Save.

That’s it. If you want to check, go to the Timers tab, find your timer in the list of timers and invoke it:

After that you can go to the Files section, open the ‘export’ folder and find your export archive. You can then download your archive and, if necessary, import into your app in the Manage > Import section.

While we hope you never need to restore your data from backups, it’s important to have a backup in place in case the worst were to happen. As they say – better safe than sorry.

Happy coding!

1 Like

Hi,
Is possible to create something similar to backup a files folder?
Thanks

Hi @Marco_Casadio1,

yes, it is possible, but we don’t have step-by-step instructions for this.
You can open a new support topic with the request.

Regards,
Stanislaw

Hello! I’ve created the service exactly as described above but it stopped to work after some months. Now, if I try to invoke the timer the system returns:
{
“code”: 9005,
“message”: “Invalid developer’s login or password”,
“errorData”: {}
}

If I login trought as BL Service User by using my main admin account the system reply “Invalid login or password”.

How can I get rid of it?

Thanks in advance

Dan

Hi Dan,

instead of Backendless.serverURL in the code, try the following value https://v4api.backendless.com

Please let me know if that works. I also updated the code listing in the article.

Regards,
Mark

Hello Mark,

thanks for your suggestion but I’ve realized that the password in the script configuration was an old one. I’ve updated it and now it’s working again.

Dan

1 Like

Hi Dan,

How do you login to Backendless Console? Do you use userid/password or login with Google?

Regards,
Mark