dexie / Dexie.js

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

Does Dexie.js work with Phonegap/Cordova? #170

Open ValeriyPogosyan opened 8 years ago

ValeriyPogosyan commented 8 years ago

The Phonegap/Cordova does not have a Dexie plugin to use it like any other third party module. Are there any results about testing the Dexie.js just by adding the script into a Phonegap/Cordova application?

dfahlander commented 8 years ago

I haven't tested it personally, but you should just include Dexie.js as either a script tag or a module (npm module name 'dexie') in case you are using requirejs or browserify. I'm not that updated with the host environments of cordova applications but it needs to support the indexedDB API. The limited implementation of indexedDB that runs on apple is also supported by Dexie but there are some gotchas.

apankov commented 8 years ago

I used Dexie.js in iOS environment together with shim https://github.com/axemclion/IndexedDBShim and some manual patches to the last. Those patches have been proposed to IndexedDBShim community but still waiting to be adjusted/integrated.

roblav96 commented 8 years ago

@apankov I'm redoing my entire cordova project with dexie and the indexeddb shim.

What patches do you propose?

apankov commented 8 years ago

@roblav96 let me please refer to my comment in IndexedDBShim issue - https://github.com/axemclion/IndexedDBShim/issues/214#issuecomment-142646810

Sorry for late reply

roblav96 commented 8 years ago

@apankov

I still can't get this working on iOS9 WK with the shim.

I'm using your shim fix too.

Says here:

// NOTE: The "_"-prefixed versions are for prioritizing IDB-shim on IOS8 before the native IDB in case the shim was included.

But there are no prefixed globals in the file :/

dfahlander commented 8 years ago

The global it looks for is idbModules which IndexedDBShim generates if included as a plain script.

The comment you mentioned is outdated and I will remove it from code.

roblav96 commented 8 years ago

Ah. OK. Thank you.

ValeriyPogosyan commented 8 years ago

I was asked to create a Cordova app with Dexie.js without any third party plugins like IndexedDBShim to run under the latest iOS 9.2.1. I used Cordova's CLI to create a XCode project and loaded the app into iPhone 6. Any other than Dexie stuff works as expected however the Dexie functions are just ignored at run time without any error messages or some other clues about what is happening in the app. Just wondering if you can give me an idea what is wrong with the project?

roblav96 commented 8 years ago

Here are the facts:

Cordova iOS UIWebView Requires indexeddb shim.

Cordova iOS WKWebView Indexeddb has not been integrated by Cordova yet.

I spent an entire week testing tons of different options because I love dexie so much but it'll never work no matter what you do.

Stick with the native sqlite plugin. There's no other option. Period.

bjomi commented 8 years ago

Actually, we use Dexie.js in production at Roombler (https://www.roombler.com). We're using wkwebview and no shim and haven't had any major issues and it generally performs well. It has been incorporated in the product ever since the release of iOS 8 and its "support" for indexeddb. The biggest issue for us, that is entirely on Apples side, is the bug that makes it impossible to have a transaction over multiple collections. Other then that, we come across minor issues from time to time that we need to work around. But as I said, over all it works good.

roblav96 commented 8 years ago

you must be using the local web server plugin. not a good idea for production but that's my opinion

dpogue commented 8 years ago

cordova-ios with the WKWebView plugin out-of-the-box supports neither IndexedDB nor WebSQL. This is a WKWebView limitation, not a Cordova problem. You need to install the local web server plugin to allow IndexedDB support.

We've used Dexie with Cordova, with no problems in the following situations:

roblav96 commented 8 years ago

You need to install the local web server plugin to allow IndexedDB support.

Data corruption is inevitable in my experience with that. Keep a close eye on your builds and the port you choose.

ValeriyPogosyan commented 8 years ago

@roblav96 @dpogue

You need to install the local web server plugin to allow IndexedDB support.

There are several WKWebView plugins available in the repository so which one did you use? Could you also provide the link to the local web server plugin you have tested/used?

dpogue commented 8 years ago

I used the Cordova core WKWebView plugin: http://npm.im/cordova-plugin-wkwebview-engine

I used the experimental core plugin for a local server: https://github.com/apache/cordova-plugins/tree/master/wkwebview-engine-localhost

nolanlawson commented 8 years ago

This seems like a documentation issue rather than a support issue. Although in an ideal world, maybe Dexie would have a "gap" plugin for Safari/iOS, similar to how it has idb-iegap for IE?

dfahlander commented 8 years ago

That's true. I've finally got access to safari browsers through an account at Browserstack. Plan to start testing continously on safari and IOS devices when time gives.

I rewrote idb-iegap but left it unfinished due to lack of time. It's actually done but I just didn't have the time to do the last debugging on it to make it working again. If me or someone else will ever finish it, it could benefit from fixing the similar safari gaps as well.

The rewritten (incomplete) shim is checked in on another branch.

reedjeffry commented 7 years ago

Hello, I am somewhat a novice to all the technologies involved while some of you here are elite so please excuse my lack of experience. Despite reading this thread prior to attempting implementation in Cordova app I tried none the less... and its working without any observable issues. However, I am wondering if there are issues that I do not observe as I am not sure how to observe what is happening on mobile device like I can in desktop browser dev tools.

I have developed an app with appery.io, Running Cordova Android 5.2.2, Cordova iOS 4.3.0, current version of Dexie and IndexedDBShim.

Testing on Android 6.0.1 and iOS 10.3.1. As I mentioned, Everything appears to be functioning without issues. Is there something I am missing? Are there situations where issues will arise? roblav96 seemed pretty confident that dexie implementation in Cordova app is not feasible.

regards, Jeff

mesqueeb commented 5 years ago

This thread is very relevant for me as I need to create a Cordova app that stores data. From my googling I found DexieJS and LokiJS, and now need to choose what I will use.

LokiJS says it supports Cordova out of the box?

To come back to DexieJS, as this is a Dexie thread, @dpogue you said:

We've used Dexie with Cordova, with no problems in the following situations:

  • cordova-ios with WKWebView

However, you also say

cordova-ios with the WKWebView plugin out-of-the-box supports neither IndexedDB nor WebSQL. You need to install the local web server plugin to allow IndexedDB support.

Does that mean that I need to install:

  1. cordova-ios
  2. WKWebView cordova plugin
  3. local web server plugin

Do you have any short guide on this?

dpogue commented 5 years ago

Do you have any short guide on this?

That information was for iOS 9's WKWebView.

IndexedDB is properly supported in WKWebView as of iOS 10, with support on iOS 10.3 and newer being quite good.

HarelM commented 4 years ago

I'm using dexie.js with cordova and iOS. In general, it works great. I'm trying to store large amount of data (~500Mb) and I'm not sure this is possible. Has anyone tried and manage to do it? Has anyone encountered a size limitation? Currently when I try to do it, the app gets stuck... :-( I'm thinking about switching to sqlite as I've read that there's no size limitation there, but it's a lot of work and I really like the concept of using IndexDB as my storage as I can easily test it in my browser. I'm using WKWebView with the local host engine on iOS 13.

crapthings commented 3 years ago

i can't make this work with cordova android.

these code works with browser, but not cordova

db = new Dexie('database')

db.version(1).stores({
  records: '_id,incoming,amount,name,tag,date,createdAt',
})

const records = _.times(100, (n) => {
  const date = faker.date.past()

  return {
    _id: Random.id(),
    name: faker.lorem.words(),
    incoming: _.sample([true, false]),
    amount: faker.finance.amount(),
    tag: _.sample(['something']),
    date,
    createdAt: new Date(),
  }
})

db.records.bulkAdd(records)
modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49930 Unhandled rejection: DataError: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path yielded a value that is not a valid key.
 DataError: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path yielded a value that is not a valid key.
Error: Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path yielded a value that is not a valid key.
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:51642:44
    at executePromiseTask (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49524:9)
    at new DexiePromise (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49338:5)
    at Object.mutate (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:51594:20)
    at Object.mutate (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:52597:38)
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:50240:31
    at checkTableInTransaction (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:50014:20)
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49957:24
    at usePSD (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49872:16)
    at newScope (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49776:14)
From previous: 
    at Object.mutate (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:51594:20)
    at Object.mutate (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:52597:38)
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:50240:31
    at checkTableInTransaction (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:50014:20)
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49957:24
    at usePSD (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49872:16)
    at newScope (http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49776:14)
    at http://localhost:12240/__cordova/packages/modules.js?hash=7d43097ecb9f3b2d50f710fbe96c7a2dfda56a18:49955:20
dfahlander commented 3 years ago

What does Random.id() return? Each object in the array provided to bulkAdd() must have a property _id (according to your schema) containing a valid indexable value.

crapthings commented 3 years ago

What does Random.id() return? Each object in the array provided to bulkAdd() must have a property _id (according to your schema) containing a valid indexable value.

its just normal string.

dfahlander commented 3 years ago

To be certain that the argument you send to db.records.bulkAdd() is indeed an array of objects where each object has a property "_id" that is a normal string, could you add the following snippet:

if (Array.isArray(records) && records.every(record => typeof record._id === "string")) {
  console.log("bulkAdd() arguments ok!");
} else {
  console.error("Not all records sent to bulkAdd() are ok", records);
}

...before calling bulkAdd().

One other thing to watch out for is whether the primary key ("_id" in your case) could have been changed after database is created. You should get another error message if so, and it is easiest fixed by deleting the db and rerunning the code - temporarily add the following before calling bulkAdd()

db.delete().then(()=>{
  return db.open();
}).then(()=>{
  ... do the bulkAdd()
});

Please let me know if any of these tips gets you further. If db deletion was required (due to a change of primary key), we must improve dexie to give better error message than the one you got.