PouchDB for Firefox Addon SDK

I started investigating a database for my Chrome and Firefox addon yesterday and came across PouchDB. PouchDB is basically a NoSQL database for the browser. It is inspired by CouchDB and can even sync to it. PouchDB has excellent cross browser compatibility uses different backends (WebSQL, IndexedDB, LevelDB for Node.js) depending on browser or js runtime capabilities. This makes it an excellent option for cross platform web applications.

CouchDB worked out of the box for Chrome extensions, however it did not play well with Firefox extensions, especially apps built with the Firefox Addon SDK (jetpack). PouchDB supports the CommonJS spec for loading modules as it supports Node.js so it shouldn’t be hard to fix this right? The main reason why it would not work was that vital components like indexedDB that are available on normal web pages aren’t available in the Firefox Addon window-less runtime context. If you use it within a normal loaded web page in the extension (i.e. resources://) it would work fine, but you would loose access to PouchDB when that web page is closed. You want to be able to access PouchDB in your main.js.

So the trick is to bring back all the missing components that PouchDB needs to run. Luckily, there wasn’t that many, so the fix was quite simple. At this time 3.3.0 was the latest version, and the following patch works fine. No guarantee for future versions:

Open up pouchdb-3.3.0.min.js and add the following lines right at the top before the comments:

[code]if (typeof require !== ‘undefined’) {
indexedDB = require(‘sdk/indexed-db’).indexedDB;
IDBKeyRange = require(‘sdk/indexed-db’).IDBKeyRange;
setTimeout = require(‘sdk/timers’).setTimeout;
clearTimeout = require(‘sdk/timers’).clearTimeout;
window = { btoa: require(‘sdk/base64’).encode,
atob: require(‘sdk/base64’).decode,
escape: require(‘sdk/querystring’).escape };
XMLHttpRequest = require("sdk/net/xhr").XMLHttpRequest;
}
[/code]

That’s it, and you should be able to use require on your main.js like so (assuming you put pouchdb-3.3.0.min.js in the same lib directory):

[code]var PouchDB = require(‘./pouchdb-3.3.0.min.js’);[/code]

One last piece of advice is that webpages in your extension that are run under resources:// will not be able to access data from PouchDB/IndexedDB created in the main.js window-less context. They each have their own storage areas like they’re different websites. So you should pick one to use PouchDB and use messages to pass data across the contexts.

Leave a Reply

Your email address will not be published. Required fields are marked *