andpor / react-native-sqlite-storage

Full featured SQLite3 Native Plugin for React Native (Android and iOS)
MIT License
2.74k stars 521 forks source link

Can not open database in IOS #529

Open Ckakkireni opened 1 year ago

Ckakkireni commented 1 year ago

Unable to OpenDBConnection, getting below error in IOS

Unable to OpenDBConnection, getting below error in IOS

LogBox.js:154 Possible Unhandled Promise Rejection (id: 0): TypeError: Cannot read properties of undefined (reading 'open') TypeError: Cannot read properties of undefined (reading 'open') at plugin.exec (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:112856:28) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:112856:28)") at SQLitePlugin.open (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:113100:14) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:113100:14)") at new SQLitePlugin (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:112902:10) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:112902:10)") at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:113654:12 at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:112844:20 at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:112765:42 at tryCallTwo (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:28655:7) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:28655:7)") at doResolve (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:28819:15) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:28819:15)") at new Promise (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:28678:5) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:28678:5)") at _$$_REQUIRE (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.AOM:112744:23) "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesonly=false&runmodule=true&app=org.reactjs.native.example.aom:112744:23)") registerWarning @ LogBox.js:154 console.warn @ LogBox.js:71 overrideMethod @ backend.js:2082 onUnhandled @ promiseRejectionTrackingOptions.js:43 onUnhandled @ rejection-tracking.js:71 (anonymous) @ JSTimers.js:214 _callTimer @ JSTimers.js:112 callTimers @ JSTimers.js:357 callFunction @ MessageQueue.js:417 (anonymous) @ MessageQueue.js:114 guard @ MessageQueue.js:368 callFunctionReturnFlushedQueue @ MessageQueue.js:113 (anonymous) @ debuggerWorker.js:69 RCTLog.js:47 Running surface LogBox ({ initialProps = { }; rootTag = 61; })

Package.JSON file

version": "0.0.1",

"private": true,

"scripts": {

"android": "react-native run-android",

"ios": "react-native run-ios",

"start": "react-native start",

"test": "jest",

"lint": "eslint ."

},

"dependencies": {

"@types/react-native-sqlite-storage": "^5.0.2",

"react": "18.0.0",

"react-native": "0.69.1",

"react-native-sqlite-storage": "^6.0.1"

},

"devDependencies": {

"@babel/core": "^7.12.9",

"@babel/runtime": "^7.12.5",

"@react-native-community/eslint-config": "^2.0.0",

"babel-jest": "^26.6.3",

"eslint": "^7.32.0",

"jest": "^26.6.3",

"metro-react-native-babel-preset": "^0.70.3",

"react-test-renderer": "18.0.0"

},

"jest": {

"preset": "react-native"

}

Actual File Used

import { openDatabase, enablePromise } from 'react-native-sqlite-storage'; import { NativeModules } from 'react-native';

enablePromise(true);

/* export const getConnection = async () => {

const db = await openDbConnection();
console.log(db);
return db;

}

export const openDBConnection = async () => { return await openDatabase({ name: "ContactsDB", createFromLocation:'~ app_update.sqlite',location:'default'}); } */

export const getConnection = async () => {

const db = await openDbConnection();
console.log(db);
return db;

}

export const openDbConnection = async () => { console.log("openDbConnection") return await openDatabase({name: "contactsDB", location: 'default'}); }

//var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000, openCB, errorCB);

export const createTable = async (db) => { try { const query = CREATE TABLE IF NOT EXISTS CONTACTS (name TEXT, mobile TEXT, email TEXT);

    await db.executeSql(query);
} catch (error) {
    console.log("Create Table Error", error);
}

}

export const saveContact = async (db, contact) => { try { const query = INSERT INTO CONTACTS(name, mobile, email) values ('${contact.name}', '${contact.mobile}', '${contact.email}'); return await db.executeSql(query);

} catch (error) {
    console.log("saveContact Error", error);
}

}

export const fetchContacts = async (db) => { const contacts = []; try {

    const results = await db.executeSql("SELECT name, mobile, email FROM CONTACTS");
    console.log("fetchContacts results", results);
    results.forEach(result => {
        for (let index = 0; index < result.rows.length; index++) {
            const row = result.rows.item(index);
            contacts.push(row) ;

        }
    })
    return contacts;

} catch (error) {
    console.log("fetchContacts error", error);
}

} Please help me to resolve this issue

import { openDatabase, enablePromise } from 'react-native-sqlite-storage'; import { NativeModules } from 'react-native'; enablePromise(true); export const getConnection = async () => { const db = await openDbConnection(); return db; } export const openDbConnection = async () => { console.log("openDbConnection") return await openDatabase({name: "contactsDB", location: 'default'}); }

Same code worked for Android and we can openDb Connection and create tables and get data as well from DB

karlludwigweise commented 1 year ago

This is a race-condition issue. Your database is not opened yet, when your application makes the first call. It surfaces now, because openDatabase is now async. This is a temporary work around (not perfect, but works)

import {
  openDatabase,
  SQLError,
  Transaction,
  DatabaseParams,
  SQLiteDatabase,
} from "react-native-sqlite-storage";

export interface SQLiteRequest {
  query: string;
  variables: (string | number)[];
}

const databaseParams: DatabaseParams = {
  name: "app.db",
  location: "Library",
};

export class Database {
  sqlite?: SQLiteDatabase;

  constructor() {
    this.openDb();
  }

  async openDb() {
    const openedDb = await openDatabase(databaseParams);
    this.sqlite = openedDb;
  }

  async query(primary: SQLiteRequest, conditionals: SQLiteRequest[] = []) {
    if (!this.sqlite) {
      await this.openDb();
    }

    return new Promise((resolve, reject) => {
      this.sqlite!.transaction(
        (txn: Transaction) => {
          txn.executeSql(
            primary.query,
            primary.variables,
            (_t: Transaction, result: ResultSet) => {
              if (result && conditionals && conditionals.length > 0) {
                conditionals.forEach((request: SQLiteRequest) => {
                  txn.executeSql(request.query, request.variables);
                });
              }
              resolve(result);
            },
            (_t: Transaction, error: SQLError) => {
              reject(error);
            }
          );
        },
        (error: SQLError) => {
          logError(error.message, "A database error occured", {
            type: "SQLITE_ERROR",
            error,
            query: primary.query,
          });
        },
        () => {}
      );
    });
  }
}
const db = new Database();

You can use db.query() for your transactions.