Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Hi everyone, thanks in advance for your support! Please let me know if I can add any additional information to make this question clearer.

The error

I have a Capacitor project which uses capacitor-community/sqlite 6.0.1. My code works on iOS, but I'm now trying to extend it to Android. When the addUpgradeStatement method is run on the Android version of my app, I get the error: CapacitorSQLitePlugin: null.

Here are the specific error logs:

2024-11-12 21:28:13.336 25636-25765 Capacitor               com.hellolulo.lulo                   D  Sending plugin error: {"save":false,"callbackId":"111910333","pluginId":"CapacitorSQLite","methodName":"addUpgradeStatement","success":false,"error":{"message":"CapacitorSQLitePlugin: null"}}
2024-11-12 21:28:13.392 25636-25636 Capacitor/Plugin        com.hellolulo.lulo                   V  To native (Capacitor plugin): callbackId: 111910335, pluginId: CapacitorSQLite, methodName: addUpgradeStatement
2024-11-12 21:28:13.392 25636-25636 Capacitor               com.hellolulo.lulo                   V  callback: 111910335, pluginId: CapacitorSQLite, methodName: addUpgradeStatement, methodData: {"database":"productdb","upgrade":[{"toVersion":1,"statements":["CREATE TABLE IF NOT EXISTS products (\n                id INTEGER PRIMARY KEY AUTOINCREMENT,\n                upc TEXT NOT NULL,\n                size REAL NOT NULL,\n                unit TEXT NOT NULL,\n                name TEXT NOT NULL,\n                brand TEXT NOT NULL,\n                category_description TEXT NOT NULL,\n                sub_category_description TEXT NOT NULL,\n                when_created DATETIME DEFAULT (CURRENT_TIMESTAMP) \n            );","CREATE INDEX IF NOT EXISTS idx_products_upc ON products (upc);"]},{"toVersion":2,"statements":["ALTER TABLE products ADD COLUMN usda_codes;"]}]}
2024-11-12 21:28:13.393 25636-25765 com.getcap...RetHandler com.hellolulo.lulo                   V  *** ERROR CapacitorSQLitePlugin: null

Version info

  • @capacitor/core: 6.1.1
  • @capacitor-community/sqlite: 6.0.1
  • Device: Pixel 8 running Android 14.
  • Android Studio: Ladybug | 2024.2.1 Patch 2

Front-end code

The relevant front-end code is adapted from https://github.com/jepiqueau/blog-tutorials-apps/tree/main/SQLite/Part-2/ionic7-react-sqlite-app

/* Adapted from https://github.com/jepiqueau/blog-tutorials-apps/tree/main/SQLite/Part-2/ionic7-react-sqlite-app*/

import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection, capSQLiteUpgradeOptions } from '@capacitor-community/sqlite';
import { Capacitor } from '@capacitor/core';

export interface ISQLiteService {
    getPlatform(): string
    addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<void> 
    openDatabase(dbName: string, loadToVersion: number, readOnly: boolean): Promise<SQLiteDBConnection> 
    closeDatabase(dbName: string, readOnly: boolean): Promise<void>
    isConnection(dbName: string, readOnly: boolean): Promise<boolean>
};

class SQLiteService implements ISQLiteService {
    platform = Capacitor.getPlatform();
    sqlitePlugin = CapacitorSQLite;
    sqliteConnection = new SQLiteConnection(CapacitorSQLite);
    dbNameVersionDict: Map<string, number> = new Map();

    getPlatform(): string {
        return this.platform;
    }
    async addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<void> {
        try {
            await this.sqlitePlugin.addUpgradeStatement(options);
        } catch(error: any) {
            const msg = error.message ? error.message : error;
            throw new Error(`sqliteService.addUpgradeStatement: ${msg}`);
        }
        return;
    }
    async openDatabase(dbName:string, loadToVersion: number,
                readOnly: boolean): Promise<SQLiteDBConnection>  {
        this.dbNameVersionDict.set(dbName, loadToVersion);
        let encrypted = false;
        const mode = encrypted ? "secret" : "no-encryption";
        try {
            let db: SQLiteDBConnection;
            const retCC = (await this.sqliteConnection.checkConnectionsConsistency()).result;
            let isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;
            if(retCC && isConn) {
              db = await this.sqliteConnection.retrieveConnection(dbName, readOnly);
            } else {
                db = await this.sqliteConnection
                        .createConnection(dbName, encrypted, mode, loadToVersion, readOnly);
            }
            const jeepSQlEL = document.querySelector("jeep-sqlite")
      
            await db.open();
            const res = await db.isDBOpen();
            return db;
          
        } catch(error: any) {
            const msg = error.message ? error.message : error;
            throw new Error(`sqliteService.openDatabase: ${msg}`);
        }

    }
    async isConnection(dbName:string, readOnly: boolean): Promise<boolean> {
        try {
            const isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;
            if (isConn != undefined) {
                return isConn
            } else {
                throw new Error(`sqliteService.isConnection undefined`);
            }
        
        } catch(error: any) {
            const msg = error.message ? error.message : error;
            throw new Error(`sqliteService.isConnection: ${msg}`);
        }
    }
    async closeDatabase(dbName:string, readOnly: boolean):Promise<void> {
        try {
            const isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;
            if(isConn) {
                await this.sqliteConnection.closeConnection(dbName, readOnly);
            }
            return;
        } catch(error: any) {
            const msg = error.message ? error.message : error;
            throw new Error(`sqliteService.closeDatabase: ${msg}`);
        }
    }
}
export default new SQLiteService();

What I've tried

I have read the Android Quirks section of the ReadMe.

Check/Add the following: Gradle JDK version 17 Android Gradle Plugin Version 8.0.0 In variables.gradle
minSdkVersion = 22
compileSdkVersion = 33
targetSdkVersion = 33

I was unable to do this, I am instead using:

    minSdkVersion = 22
    compileSdkVersion = 34
    targetSdkVersion = 34

In AndroidManifest.xml... In res/xml create a file data_extraction_rules.xml containing:....
I did follow this advice, so my AndroidManifest.XML has:

    <application
        android:allowBackup="false"
        android:fullBackupContent="false"
        android:dataExtractionRules="@xml/data_extraction_rules"

And at android/app/src/main/res/xml/data_extraction_rules.xml I have:

<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
    <cloud-backup>
      <exclude domain="root" />
      <exclude domain="database" />
      <exclude domain="sharedpref" />
      <exclude domain="external" />
    </cloud-backup>
    <device-transfer>
      <exclude domain="root" />
      <exclude domain="database" />
      <exclude domain="sharedpref" />
      <exclude domain="external" />
    </device-transfer>
</data-extraction-rules>

I've also read a few similar discussions, but many of them land on the solutions suggested above, which don't seem to be working for me.

I'm new to Android development, so please let me know if there's any other information I should be sharing! Thanks again for your help. 🙏🏻

You must be logged in to vote

Replies: 2 comments

Comment options

I'm following up here to share that I have solved my problem, though I still don't understand the root cause. I simply deleted my "android" folder (as generated by Capacitor) and re-ran npx cap add android.

It's obviously not a great solution (I had to re-implement some Java plugins I'd written, and I still don't understand the root cause of the issue) but I'm sharing this in case it helps anyone who is experiencing similar problems!

You must be logged in to vote
0 replies
Comment options

Hey, I found an easier way to avoid this error:

Locate the run/debug configuration menu in Android Studio. Select the drop-down menu associated with your deployment target (e.g., "app"), and click on "Edit Configurations."

Within the "Run/Debug Configurations" dialog:
Tick the option labeled "Clear app storage before deployment." This ensures any previous state is cleared during deployment, which was causing the error on my end.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.