indexed-db

Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.

From Firefox 53 onwards, no new legacy add-ons will be accepted on addons.mozilla.org (AMO).

From Firefox 57 onwards, WebExtensions will be the only supported extension type, and Firefox will not load other types.

Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to WebExtensions if they can. See the "Compatibility Milestones" document for more.

A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.

Experimental

Exposes the IndexedDB API to add-ons.

Usage

Scripts running in web pages can access IndexedDB via the window object. For example:

window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
var request = window.indexedDB.open("MyDatabase");
request.onerror = function(event) {
  console.log("failure");
};
request.onsuccess = function(event) {
  console.log("success");
};

Because your main add-on code can't access the DOM, you can't do this. So you can use the indexed-db module to access the same API:

var { indexedDB } = require('sdk/indexed-db');
var request = indexedDB.open('MyDatabase');
request.onerror = function(event) {
  console.log("failure");
};
request.onsuccess = function(event) {
  console.log("success");
};

Most of the objects that implement the IndexedDB API, such as IDBTransaction, IDBOpenDBRequest, and IDBObjectStore, are accessible through the indexedDB object itself.

The API exposed by indexed-db is almost identical to the DOM IndexedDB API, so we haven't repeated its documentation here, but refer you to the IndexedDB API documentation for all the details.

The database created will be unique and private per add-on, and is not linked to any website database. The module cannot be used to interact with a given website database. See bug 778197 and bug 786688.

Example

This example uses the action button API, which is only available from Firefox 29 onwards.

Here's a complete add-on that adds two buttons to the browser: the button labeled "Add" adds the title of the current tab to a database, while the button labeled "List" lists all the titles in the database.

The add-on implements helper functions open(), addItem() and getItems() to open the database, add a new item to the database, and get all items in the database.

var { indexedDB, IDBKeyRange } = require('sdk/indexed-db');
var database = {};
database.onerror = function(e) {
  console.error(e.value)
}
function open(version) {
  var request = indexedDB.open("stuff", version);
  request.onupgradeneeded = function(e) {
    var db = e.target.result;
    e.target.transaction.onerror = database.onerror;
    if(db.objectStoreNames.contains("items")) {
      db.deleteObjectStore("items");
    }
    var store = db.createObjectStore("items",
      {keyPath: "time"});
  };
  request.onsuccess = function(e) {
    database.db = e.target.result;
  };
  request.onerror = database.onerror;
};
function addItem(name) {
  var db = database.db;
  var trans = db.transaction(["items"], "readwrite");
  var store = trans.objectStore("items");
  var time = new Date().getTime();
  var request = store.put({
    "name": name,
    "time": time
  });
  request.onerror = database.onerror;
};
function getItems(callback) {
  var cb = callback;
  var db = database.db;
  var trans = db.transaction(["items"], "readwrite");
  var store = trans.objectStore("items");
  var items = new Array();
  trans.oncomplete = function() {
    cb(items);
  }
  var keyRange = IDBKeyRange.lowerBound(0);
  var cursorRequest = store.openCursor(keyRange);
  cursorRequest.onsuccess = function(e) {
    var result = e.target.result;
    if(!!result == false)
      return;
    items.push(result.value.name);
    result.continue();
  };
  cursorRequest.onerror = database.onerror;
};
function listItems(itemList) {
  console.log(itemList);
}
open("1");
var add = require("sdk/ui/button/action").ActionButton({
  id: "add",
  label: "Add",
  icon: "./add.png",
  onClick: function() {
    addItem(require("sdk/tabs").activeTab.title);
  }
});
var list = require("sdk/ui/button/action").ActionButton({
  id: "list",
  label: "List",
  icon: "./list.png",
  onClick: function() {
    getItems(listItems);
  }
});

Note that to run this add-on you'll need to provide icons named "add.png" and "list.png" in the add-on's "data" directory.

Globals

Properties

indexedDB

Enables you to create, open, and delete databases. See the IDBFactory documentation.

IDBKeyRange

Defines a range of keys. See the IDBKeyRange documentation.

DOMException

Provides more detailed information about an exception. See the DOMException documentation.

Document Tags and Contributors

Tags: 
 Contributors to this page: wbamberg, maybe, fred.wang
 Last updated by: wbamberg,