Search code examples
sqliteionic-frameworkelectroncapacitor

Can I create an Ionic app that runs offline on a Windows machine with an SQLite database?


I am trying to create a prototype of an Ionic+Angular application that can run offline on a Windows machine (by using Capacitor and Electron) and can store data in an SQLite database.

However, after I start the app (npx cap open electron) the database is not created with the following error:

Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'then')
TypeError: Cannot read properties of undefined (reading 'then')"

How can I fix this error?

This is the code where the database is initialized:

import { Injectable } from '@angular/core';
import { Platform } from '@ionic/angular';
import { Song } from './song';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { SQLitePorter } from '@awesome-cordova-plugins/sqlite-porter/ngx';
import { SQLite, SQLiteObject } from '@awesome-cordova-plugins/sqlite/ngx';

@Injectable({
  providedIn: 'root',
})

export class DbService {
  private storage: SQLiteObject;
  songsList: any = new BehaviorSubject([]);
  private isDbReady: BehaviorSubject<boolean> = new BehaviorSubject(false);
  constructor(
    private platform: Platform,
    private sqlite: SQLite,
    private httpClient: HttpClient,
    private sqlPorter: SQLitePorter
  ) {
    this.initDb();
  }

  initDb() {
    this.platform.ready().then(() => {
      this.sqlite
        .create({
          name: 'positronx_db.db',
          location: 'default',
        })
        .then((db: SQLiteObject) => {
          this.storage = db;
          this.getFakeData();
        })
        .catch((error) => {
          console.error(error);
        });
    });
  }
}

I successfully created an empty ionic app using Capacitor and Electron to wrap it to run as a desktop application on Windows by following this tutorial.

To add the SQLite database I followed this tutorial. Initially I got some dependency conflict error, but following this post I replaced the @ionic-native packages with @awesome-cordova-plugins which resolved the dependency conflict error, leaving me with the error described above.

I found this post which describes my problem pretty accurately and suggests to use Web SQL, since apparently the sqlite plugin cannot be used in a browser. Web SQL is deprecated though, and since I want to have a Windows desktop app I don't necessarily need it to work in a browser. Is there any way to work around this restriction?

I tried using a capacitor command to serve the app with electron as the platform (ionic capacitor run electron) to run it as a Windows app directly instead of a web app, but then I get [ERROR] No devices or emulators found. I am not sure how to add a Windows device or emulator, or if this is even the correct approach to fix this issue.

I considered using Ionic Storage instead of SQLite as suggested here, but there is a lot of complex relational data and it does need to be completely functional offline, which seems to mean that I need SQLite.


Solution

  • I ended up finding this repository which implements a complete starter solution for an Ionic 7 Angular 16 app while using the @capacitor-community/sqlite plugin with Capacitor 5 as their offline database.

    Initially I had some problems running it with Electron (npm run electron:start) and got the error

    The module .\electron\node_modules\better-sqlite3-multiple-ciphers\build\Release\better_sqlite3.node' was compiled against a different Node.js version using NODE_MODULE_VERSION 108. This version of Node.js requires NODE_MODULE_VERSION 116. Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install)

    I was able to fix the error by following the second answer on this post, executing the commands from the ./electron directory and specifying the electron version for the rebuild command (node_modules\.bin\electron-rebuild -f -w <your-electron-version>).