dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.11k stars 635 forks source link

React Native support? #354

Open bnolan opened 7 years ago

bnolan commented 7 years ago

I love my experience with Dexie so far. What's the best / easiest way to get dexie working on react native? I was thinking of using indexeddbshim + react native sqlite bindings - or maybe just port the parts of dexie I use to operate on sqlite directly. Has there been any discussion about this - or other projects like dexie that target other databases?

dfahlander commented 7 years ago

I think indexeddbshim provides indexedDB on node. No, there's not been so much discussion about this but I'm also having ideas about making it possible to use Dexie towards other data sources. But today it's to much bound to indexedDB so that needs to be changed first.

bnolan commented 7 years ago

I'll let you know if I have any luck with getting it to run on sqlite.

mbrevda commented 7 years ago

I was wondering about react-native support, too. Has anyone had any success with this?

douglasjunior commented 5 years ago

First of all, thanks for the amazing tool.

Is there any plan to create adapters for Dexie (like PouchDB adapters), which makes it possible to store data in other types of storage? As SQLite in React Native or Electron, MySQL in NodeJS or Electron and etc?

I have an interest in porting Dexie to other platforms, or creating an adapters framework that enables this transition.

Could some maintainer guide me where to start?

EDIT:

I think I should start with file https://github.com/dfahlander/Dexie.js/blob/master/src/dbcore/dbcore-indexeddb.ts, is there any other file that accesses IndexedDB directly?

dfahlander commented 5 years ago

Hi, and thanks for your nice words. IndexedDB is still accesssed directly (outside DBCore) when opening a database. That code starts from Dexie.open() in dexie.ts under classes/dexie and the code that does this origins from dexie-open.ts. Also, creating transaction is directly done in transaction.ts, in the create() method using the native idbdb.transaction() method. Doing "Find all references" from db.idbdb or trans.idbtrans, might reveal locations that talk directly to the native IndexedDB interface. The rewrite to use DBCore was one of the latest changes. There's a method in DBCore: transaction() that is intended to be called here, but the code still do not take that path.

Feel free to experiment on how to improve the adaptivity of Dexie. You're very welcome. There might be some architectural changes needed, such as introducting a new DBCoreFactory interface, or extending DBCore.

Thanks, David

douglasjunior commented 5 years ago

Thanks for the feedback @dfahlander.

No doubt we have a lot of work here, the good news is that this is fun!

I have seen that exists plans to change the architecture here #602, so I think it would take longer than I can wait.

Initially, I will try to create the version for React Native from my fork, with this I will learn more about the architecture and eventually I can contribute with the refactoring in the main repository.

dfahlander commented 5 years ago

I just closed #602 as it was an old thread. All that discussion originated from the state of the code before the typescript-rewrite. There is no current refactoring going on so I think the risk for conflicts are low right now. I'll try keeping you updated if that will change.

bkniffler commented 5 years ago

Wonder if it works with https://github.com/axemclion/IndexedDBShim/issues/313

geofmureithi-zz commented 3 years ago

For anyone snooping around, I was able to work with Dexie on react-native:

import Dexie from 'dexie';
import SQLite from 'react-native-sqlite-2';
import setGlobalVars from '@indexeddbshim/indexeddbshim/dist/indexeddbshim-noninvasive';
let win = {}
setGlobalVars(win, { 
  checkOrigin: false, 
  win: SQLite, 
  deleteDatabaseFiles: false,
  useSQLiteIndexes: true
});

class MyDexie extends Dexie {
  constructor(name: string) {
    super(name, {
      indexedDB: win.indexedDB,
      IDBKeyRange: win.IDBKeyRange,
    });
  }
}
de1mat commented 2 years ago

For anyone snooping around, I was able to work with Dexie on react-native

Curious how well this is going for you. Are you using it in a production app?

PEZO19 commented 10 months ago

Can someone please point out what pros/cons does dexie might have in case of React Native environment compared to WatermelonDB or RxDB? @dfahlander @geofmureithi-zz

j10ra commented 4 months ago

I've manage to create an instance for both web and android. I'm open to any suggestions here but this works together with expo-sqlite and dexie. No need to eject

db.ts

import Dexie, { Table } from 'dexie';
import { Platform } from 'react-native';
import * as SQLite from 'expo-sqlite';
import setGlobalVars from 'indexeddbshim/dist/indexeddbshim-noninvasive';

const win = {};

if (Platform.OS !== 'web') {
  setGlobalVars(win, {
    checkOrigin: false,
    win: SQLite,
    deleteDatabaseFiles: false,
    useSQLiteIndexes: true,
  });
}

export interface Friend {
  id?: number;
  name: string;
  age: number;
}

export class IndexDb extends Dexie {
  friends!: Table<Friend>;

  constructor() {
    super('mydb', {
      // The indexedDB and IDBKeyRange are provided by the indexeddbshim
      indexedDB: Platform.OS === 'web' ? window.indexedDB : win.indexedDB,
      IDBKeyRange: Platform.OS === 'web' ? window.IDBKeyRange : win.IDBKeyRange,
    });

    this.version(1).stores({
      friends: '++id, name, age', // Primary key and indexed props
    });
  }
}

export const db = new IndexDb();

package.json

"expo-sqlite": "~13.2.2",
"indexeddbshim": "^13.0.0",
"react-native": "0.73.4",
"expo": "~50.0.8",
"dexie": "^3.2.5",
"dexie-react-hooks": "^1.1.7",

sampleComponent.tsx

export default function App() {
  const friends = useLiveQuery(() => db.friends.toArray());
  const addFriend = () => {
    db.friends.add({ name: 'John', age: 25 });
  };

  return (
    <Box w="$full" h="$full" justifyContent="center">
      <Center>
        <Button onPress={addFriend}>
          <Text>Add a friend</Text>
        </Button>

        {friends?.map((friend) => <Text key={friend.id}>{friend.name}</Text>)}
      </Center>
    </Box>
  );
}
Stewartarmbrecht commented 1 week ago

@j10ra Have you used this in production, or have you done any performance testing on it?

shovel-kun commented 1 week ago

The solution @j10ra provided gave me this error:

ERROR  Error opening database: [MissingAPIError: IndexedDB API missing. Please visit https://tinyurl.com/y2uuvskb]

packages:

    "@expo/vector-icons": "^14.0.2",
    "@react-navigation/native": "^6.0.2",
    "dexie": "^4.0.7",
    "dexie-react-hooks": "^1.1.7",
    "expo": "~51.0.18",
    "expo-constants": "~16.0.2",
    "expo-font": "~12.0.7",
    "expo-linking": "~6.3.1",
    "expo-router": "~3.5.17",
    "expo-splash-screen": "~0.27.5",
    "expo-sqlite": "~14.0.4",
    "expo-status-bar": "~1.12.1",
    "expo-system-ui": "~3.0.7",
    "expo-web-browser": "~13.0.3",
    "indexeddbshim": "^13.0.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.74.3",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "4.10.1",
    "react-native-screens": "3.31.1",
    "react-native-web": "~0.19.10"

New Architecture is not enabled. Any guidance?

dfahlander commented 1 week ago

https://dexie.org/docs/DexieErrors/Dexie.MissingAPIError links to: Using Dexie with IndexedDBShim

const setGlobalVars = require('indexeddbshim');

global.window = global; // We'll allow ourselves to use `window.indexedDB` or `indexedDB` as a global
setGlobalVars(); // See signature below
shovel-kun commented 5 days ago

Thanks @dfahlander,

The issue was expo-sqlite.

As of expo-sqlite v14, if you want to use @j10ra's code snippet you need to import from expo-sqlite/legacy, else you'll get the MissingAPIError error I described above. Expo changed their default API to expo-sqlite/next (See https://docs.expo.dev/versions/latest/sdk/sqlite/).

I'm not sure if its possible to shim their reworked API now.

aretrace commented 5 days ago

I'm not sure if its possible to shim their reworked API now.

@shovel-kun "now" as in a general timeframe (i.e., not at this time), or "now" as in now that their API has changed (i.e., not possible at all)?

shovel-kun commented 4 days ago

@aretrace

The latter. If anyone has a workaround, do share.