indexeddbshim / IndexedDBShim

A polyfill for IndexedDB using WebSql
Other
967 stars 191 forks source link

shim does not work in iOS8 Safari or Chrome #167

Closed ls-jamie-hill closed 9 years ago

ls-jamie-hill commented 10 years ago

Since the release of iOS8, the shim has stopped working in both Safari and Chrome (and UIWebView which Chrome essentially runs under).

In Safari at least, this seems to be due to the addition of window.indexedDB and the fact that it is readonly. However, I've hit other issues with using indexedDB on Safari iOS8 so would be happy to use this shim to continue to talk to webSQL which is still supported.

Has anyone had any luck getting this to work in iOS8? or the jquery.indexeddb.js library?

l33z3r commented 10 years ago

This is a big issue for me also, can anybody shed some light on a fix?

ls-jamie-hill commented 10 years ago

So I managed to put together a fix for this, or at least a workaround, which is to use the shim rather than trying to get indexedDB itself to work on iOS8 as it doesn't seem to be compatible with any libraries I've tried.

Because window.indexedDB is read-only, I instead assign the various vars for the shim to window._indexedDB, window._IDBDatabase, etc - that is, everything inside of the __useShim() function. And then useragent match to flag iOS8 as poorIndexedDbSupport to make sure it uses the shim.

Once you've done that then you can update whatever indexeddb library you're using as necessary. In my case, with jquery.indexeddb.js it was just assigning the _ variables ahead of the regular ones, like: var indexedDB = window._indexedDB || window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

l33z3r commented 10 years ago

Oh, yes, I understand the problem now.

Your workaround is perfect.

Thanks for sharing the solution!

pixel9 commented 10 years ago

FYI, be careful when using the shim in this way since other indexedDB related features like window.IDBKeyRange ARE implemented. You'll need to make sure all indexedDB related calls are using the shim or none at all.

miqmago commented 9 years ago

I have the same problem. I've seen that window.indexedDB is 'null' in ios8 so its not "undefined" and then it fails the condition at line 1723:

if ((typeof window.indexedDB === "undefined" || poorIndexedDbSupport) && typeof window.openDatabase !== "undefined") {

Replaced by:

if ((typeof window.indexedDB === "undefined" || window.indexedDB === null || poorIndexedDbSupport) && typeof window.openDatabase !== "undefined") {

But getting error:

[Error] TypeError: Attempted to assign to readonly property. __useShim (IndexedDBShim.js, line 1687) (funció anònima) (IndexedDBShim.js, line 1724) global code (IndexedDBShim.js, line 1741)

miqmago commented 9 years ago

@jamiejhill solution works perfectly. I've replaced all indexedDB by _indexedDB in IndexedDBShim.js and also replaced window.indexedDB by window._indexedDB in db.js.

Thanks!

limefrogyank commented 9 years ago

this fix works very well, thanks! For typescript users, you also need to add:

declare var _indexedDB: IDBFactory;

interface IDBEnvironment {
    _indexedDB: IDBFactory 
}

to a typings file (usually lib.d.ts)

mohan-evolent commented 9 years ago

could you guys publish the fix step by step? that would really help for our project

gracezlive commented 9 years ago

jamiehill's solution worked like a charm. :) Thanks!

JamesMessinger commented 9 years ago

Closing this issue, since it's actually a WebKit bug. The window.indexedDB variable is read-only, so we can't shim it. Until WebKit fixes the bug, there are two possible workarounds that you can use:

  1. Use window.shimIndexedDB instead of window.indexedDB We always add this property to the window object, even if the browser natively supports IndexedDB. This allows you to use the shim instead of the native implementation, which is useful because some native implementations are really buggy (Safari and IE).
  2. Create an indexedDB variable in your closure By creating a variable named indexedDB, all the code within that closure will use the variable instead of the window.indexedDB property. For example:
(function() {
    // This works on all browsers, and only uses IndexedDBShim as a final fallback 
    var indexedDB = window.indexedDB || 
                    window.mozIndexedDB ||
                    window.webkitIndexedDB || 
                    window.msIndexedDB || 
                    window.shimIndexedDB;

    // This code will use the native IndexedDB, if it exists, or the shim
    indexedDB.open("MyDatabase", 1);
})();
satisne commented 8 years ago

I implemented jamiehill's solution even though I am getting "Unable to Shim IndexedDB" issue when I use the emulator as iPad8.1. Can anybody please help me on this.

roblav96 commented 8 years ago

same here. i think this is a bust. looks like im going back to sqlite

brettz9 commented 8 years ago

FWIW, I got the same "Unable to Shim IndexedDB" error in Chrome desktop and was able to resolve by adding the line delete window.indexedDB; before the shimming directive.