Non-standard
This feature is not on a current W3C standards track, but it is supported on the Firefox OS platform. Although implementations may change in the future and it is not supported widely across browsers, it is suitable for use in code dedicated to Firefox OS apps.
This API is available on Firefox OS for internal applications only.
The Data Store API provides a powerful, flexible storage mechanism for Firefox OS applications to use to store and share data. It is basically an intermediary store to allow multiple applications to share data between one another quickly, efficiently, and securely, in spite of differences between API data structures, formats, etc.
Data Store API concepts and usage
The Data Store API was created to allow multiple Firefox OS apps, with potentially different data structures and storage mechanisms, to create, maintain and share the same data objects efficiently between one another. Each app can then import the data into its own local IndexedDB to index according to their specific query needs. This is not necessary however, and you can just write directly to the Data Store API data store.
Note: For more information on how Data Store API works, including working examples, consult our Using the Data Store API article.
Note: The Data Store API is available in Web Workers, from Firefox 32 onwards (Firefox OS 2.0; see bug 949325.)
There are several possible reasons to use this API, including:
- It lets an application create data that it can then share with other applications.
- It lets multiple applications supply data to the same data store.
- It supports read-only data stores such as Facebook contacts (that is, it lets one app create and maintain the data while other apps can read the data from the store).
- It supports read/write data stores, so that multiple applications can contribute data to the same data store. An example would be the device's standard contacts, which can be updated by both the built-in Contacts app and third-party apps.
- It supports keeping an application-locale cache of a data store, with notifications to let the app know when there have been changes to the master data store so that the cache can be updated.
This Data Store API datastore is owned by a specific app (as specified by the datastores-owned
field in the app's manifest — see Manifest_fields, below), and this ownership gives the app the right to populate the data store and declare whether the data store is readonly
(meaning other apps can only read the data) or readwrite
(meaning other apps can modify the data as well as read it.) Other apps can gain access to a datastore by naming it in the datastores-access
field of their app manifest.
When an app wants to access a datastore, it has to call Navigator.getDataStores()
; The result value of this method is a Promise
object that will resolve with an array of DataStore
objects. From these DataStore
objects, the app can read and modify values using various methods of the DataStore
such as DataStore.get()
and DataStore.insert()
.
Note: The Data Store API currently has no imposed limitations on storage space. This is likely to be updated in the near future.
Change management and conflict resolution
When multiple apps make changes to a Data Store, it could create conflicts. However, any change you make (using DataStore.update()
, DataStore.add()
, etc.) is given a revisionId
, a UUID received in the change
event fired whenever a operation is performed on the Data Store by any app with access to it. This can be read from the DataStore.revisionId
property.
The revisionId
property can be included as an optional parameter in the DataStore.add()
, DataStore.put()
, DataStore.remove()
, DataStore.clear()
, and DataStore.sync()
methods. Doing so basically uses that revisionId
as a conflict avoider — the operation is aborted if that revisionId
is not the last one known by the Data Store (i.e. if another app has made a more recent change).
When the change
event is fired, it receives a DataStoreChangeEvent
object, giving the app access to:
DataStoreChangeEvent.revisionId
: The last knownrevisionId
.DataStoreChangeEvent.id
: The key of the changed object, which can be null if the operation was aclear()
.DataStoreChangeEvent.operation
: The operation that was performed —add()
,remove()
, etc.DataStoreChangeEvent.owner
: The manifest URL of the app that performed this operation.
When an app wants to see what has changed, it can do it by asking for the ‘delta’ between the last known revisionId
and the current one. This is done using the DataStore.sync()
method. You can allow your apps to deal with data changes by running a sync()
on application startup and onchange
, passing it the current revisionId
to check against.
Filtering data
As hinted at above, the Data Store API is not responsible for filtering data or building indexes; instead it leaves this up to the the app's local storage mechanism (usually an IndexedDB); The Data Store API simply allows the local indexes to be kept up to date, via the DataStoreCursor
object, created when sync()
is invoked.
Manifest fields
The data store owner's manifest MUST include the datastores-owned
field to claim ownership, for example:
"datastores-owned": { "myData": { "access": "readwrite", "description": "my data store" } }
You can include multiple properties to represent different data stores, and each one can use readonly
/readwrite
to specify whether the data store can be read/modified by other applications. A description is also included to describe the purpose of the data store.
Other applications that want to access (not own) the data store must include the datastores-access
field, for example:
"datastores-access": { "myData": { "access": "readonly", "description": "Read and modify my data store" } }
Without this field being specified, the default behavior is "no access". Again, multiple properties can be included if you want to access multiple data stores, and an access of readonly
or readwrite
can be set to declare what access type is needed by the app.
In terms of permissions, the Data Store owner always wins against the 3rd party apps. if the owner declares "readonly": true
in its manifest, any 3rd party app will be in readonly
mode also, even if they declare "access": "readwrite"
in their manifests. Of course, this isn’t much use if the owner allows the Data Store to be modified by third party apps, so for the moment, Data Store is a certified API. It is likely to come down to privileged when the security model is finalized.
Note: Remember also that in such cases you need to use the type field in your manifest to explicitly declare that your app is an internal/certified app: "type": "certified"
.
DataStore API Interfaces
The Data Store API contains the following interfaces:
DataStore
- The
DataStore
interface represents a retrieved set of data, and includes standard properties for accessing the store's name, owner, etc., methods for reading, modifying and syncing the data, and theonchange
event handler for reacting to changes to the data. DataStoreCursor
- This interface allows the app to iterate through a list of
DataStoreTask
objects representing the change history of the data store, for use when synchronising the data. DataStoreChangeEvent
- This interface represents the event related to a record changed in the data store, i.e. this is returned once a change is made and the
change
event is fired (seeDataStore.onchange
for the handler), for use when synchronizing individual changes. DataStoreTask
- This interface represents a record changed in the data store when a
DataStoreCursor
is used to iterate through the data store's change history.
Examples
We have written a couple of examples that go together, to explain how different apps can make different use of the same data store:
- The Data Store Contacts Editor creates a data store called 'contacts' on the device it is installed on, adds some default data to it, and allows the user to add new contacts to the store and delete contacts.
- The Data Store Contacts Viewer has readonly access to the 'contacts' data store; it grabs data from it and displays it in a user interface, along with a Google map of the selected user's location, displayed in an
<iframe>
to get around certified app CSP restrictions.
Keep referring to these examples and read Using the Data Store API for explanations and code samples.
Note: Be aware that to test data store examples you need to make sure your apps are internal/certified (see above for manifest fields needed), and use App Manager or WebIDE to simulate an environment where a internal/certified app can be run. Follow these links to find out how to do this using each tool: App Manager: Debugging Certified Apps and WebIDE: Debugging Certified Apps.
Specifications
Specification | Status | Comment |
---|---|---|
Data Store API | Draft |
The discussion concerning this API's creation happened in various Mozilla mailing lists and other places. A summary of the discussion and further pointers can be found on the Mozilla Wiki. For further feedback and questions, send mail to the dev-webapi mailing list.
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
Basic support | No support | No support | No support | No support | No support |
Feature | Android | Chrome | Firefox Mobile (Gecko) | Firefox OS | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|---|
Basic support | No support | No support | No support | 1.0.1 | No support | No support | No support |
Available in web workers | No support | No support | No support | 2.0 | No support | No support | No support |