Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to load better_sqlite3.node module with WatermelonDB on React Native #1796

Open
oushima opened this issue May 16, 2024 · 1 comment
Open

Comments

@oushima
Copy link

oushima commented May 16, 2024

Description

I am encountering an issue where the better_sqlite3.node module fails to load when using WatermelonDB in the web version of my React Native project. The mobile versions (iOS and Android) work fine. The error message suggests that the module cannot be found, although it exists in the expected directory.

Error Message

[🍉] Uh-oh. Database failed to load, we're in big trouble. This might happen if you didn't set up native code correctly (iOS, Android), or if you didn't recompile native app after WatermelonDB update. It might also mean that IndexedDB or SQLite refused to open. Error: Failed to open the database. - Unknown named module: "/Users/oushima/Public/IngredientInspector/frontend/build/better_sqlite3.node"
    at Database.open (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/Database.js:30:13)
    at new Database (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/Database.js:14:10)
    at DatabaseDriver.init (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js:77:21)
    at DatabaseDriver.initialize (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js:60:10)
    at DatabaseBridge.apply [as initialize] (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js:32:14)
    at SqliteNodeDispatcher.call (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/makeDispatcher/index.js:18:12)
    at SQLiteAdapter._init (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js:86:22)
    at withCallback (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js:47:13)
    at /Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/utils/fp/Result/index.js:10:5
    at new Promise (<anonymous>)
Error: Failed to open the database. - Unknown named module: "/Users/oushima/Public/IngredientInspector/frontend/build/better_sqlite3.node"
    at Database.open (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/Database.js:30:13)
    at new Database (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/Database.js:14:10)
    at DatabaseDriver.init (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js:77:21)
    at DatabaseDriver.initialize (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js:60:10)
    at DatabaseBridge.apply [as initialize] (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js:32:14)
    at SqliteNodeDispatcher.call (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/makeDispatcher/index.js:18:12)
    at SQLiteAdapter._init (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js:86:22)
    at withCallback (/Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js:47:13)
    at /Users/oushima/Public/IngredientInspector/frontend/node_modules/@nozbe/watermelondb/utils/fp/Result/index.js:10:5
    at new Promise (<anonymous>)

Steps to Reproduce

Install WatermelonDB and better-sqlite3 in a React Native project.
Configure WatermelonDB with SQLiteAdapter.
Run the project on the web.

Expected Behavior

The better_sqlite3.node module should load correctly, and the database should initialize without errors on the web version.

Observed Behavior

The web version fails to load the database, throwing an error indicating that the better_sqlite3.node module is an unknown named module. The iOS and Android versions work correctly.

Environment

├── @babel/[email protected]
├── @expo/[email protected]
├── @expo/[email protected]
├── @expo/[email protected]
├── @morrowdigital/[email protected]
├── @nozbe/[email protected]
├── @nozbe/[email protected]
├── @react-navigation/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

The better_sqlite3.node file exists in the node_modules/better-sqlite3/build/Release directory.
I've tried clearing the npm cache, reinstalling dependencies, rebuilding native modules, and ensuring the path resolution is correct.
Other native modules load without issues.

Any guidance or suggestions to resolve this issue would be greatly appreciated.

@Merott
Copy link

Merott commented May 30, 2024

I ran into the same issue and realised we need to use LokiJS for web. It's in the docs:

The above will work on React Native (iOS/Android) and NodeJS. For the web, instead of SQLiteAdapter use LokiJSAdapter

I've created adapter.ts and adapter.web.ts:

// adapter.ts

import { type LokiAdapterOptions } from '@nozbe/watermelondb/adapters/lokijs'
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'
import { SQLiteAdapterOptions } from '@nozbe/watermelondb/adapters/sqlite/type'

export const createAdapter = (
  options: Pick<
    SQLiteAdapterOptions,
    // Accept only the options shared between SQLiteAdapterOptions and LokiAdapterOptions
    Extract<keyof SQLiteAdapterOptions, keyof LokiAdapterOptions>
  >,
) =>
  new SQLiteAdapter({
    jsi: true,
    ...options,
  })
// adapter.web.ts

import LokiJSAdapter, {
  type LokiAdapterOptions,
} from '@nozbe/watermelondb/adapters/lokijs'
import { type SQLiteAdapterOptions } from '@nozbe/watermelondb/adapters/sqlite/type'

export const createAdapter = (
  options: Pick<
    LokiAdapterOptions,
    // Accept only the options shared between LokiAdapterOptions and SQLiteAdapterOptions
    Extract<keyof LokiAdapterOptions, keyof SQLiteAdapterOptions>
  >,
) =>
  new LokiJSAdapter({
    useWebWorker: false,
    useIncrementalIndexedDB: true,
    ...options,
  })

Use createAdapter to create the appropriate adapter when creating the database instance:

// database.ts

import { Database } from '@nozbe/watermelondb'

import { Post } from './models/Post'
import { createAdapter } from './adapter' // <---- imports from adapter.web.ts on web
import { schema } from './schema'

export const database = new Database({
  adapter: createAdapter({ schema }),
  modelClasses: [Post],
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants