Alternative to 'Application.storage'

I’ve been using ‘Application.storage’ in many of my extensions. Apparently this has been deprecated around Fx 40. I get a warning message in the console that reads:

Thu Aug 13 2015 16:37:22
Error: DEPRECATION WARNING: FUEL is deprecated, you should use the add-on SDK instead.
You may find more details about this deprecation at: https://developer.mozilla.org/Add-ons/SDK/
jar:file:///C:/Program%20Files%20(x86)/Firefox%20Developer%20Edition/browser/omni.ja!/components/fuelApplication.js 1458 Application
jar:file:///C:/Program%20Files%20(x86)/Firefox%20Developer%20Edition/browser/omni.ja!/components/fuelApplication.js 726 af_ci
chrome://febe/content/febe.js 11437 FEBE.errorConsole
chrome://febe/content/febe.js 358 FEBE.febeLoad
chrome://febe/content/febe.js 28 null
null 0 null

Source file: resource://gre/modules/Deprecated.jsm
Line: 79

I looked briefly at the documentation for the SDK but didn’t see anything that might replace ‘Application.storage’. Besides, I was under the impression that the SDK was for writing ‘restart-less’ extensions. I’m still developing with XUL overlays so I’m not sure the SDK applies to me.

I’m assuming that ‘Application.storage’ is part of the FUEL implementation (even though I don’t specifically load it (e.g., ‘var Application = Components.classes["@mozilla.org/fuel/application;1"].getService(Components.interfaces.fuelIApplication);’).

Is there another acceptable way to emulate what the ‘Application.storage’ functions do?

I believe that you may be looking for https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage

Reading that link gave me some sample code:

var ss = require("sdk/simple-storage");
ss.storage.myArray = [1, 1, 2, 3, 5, 8, 13];
ss.storage.myBoolean = true;
ss.storage.myNull = null;
ss.storage.myNumber = 3.1337;
ss.storage.myObject = { a: "foo", b: { c: true }, d: null };
ss.storage.myString = "O frabjous day!";

but trying to run it in a javascript shell gives me a “required not defined” error. After a little research, I found that I may have to install jpm in order to use any part of the SDK. That seems like a little bit of overkill just to get one simple function to work.

Is there a better, simpler way or am I just not understanding the bigger picture?

This is how simple storage works. It creates a folder in your ProfD folder which is your profile directory: https://github.com/mozilla/addon-sdk/blob/master/lib/sdk/simple-storage.js#L188

let storeFile = Cc["@mozilla.org/file/directory_service;1"].
                getService(Ci.nsIProperties).
                get("ProfD", Ci.nsIFile);
storeFile.append(JETPACK_DIR_BASENAME);
storeFile.append(jpSelf.id);
storeFile.append("simple-storage");
file.mkpath(storeFile.path);
storeFile.append("store.json");
return storeFile.path;

The exact location of the file made is in a your profile folder, in a folder named “jetpack” then your addon id, then a folde calld simple-storage, then in a file in that folder called store.json

What I do is just use the same paths but use OS.File

What I do is I recreated the above but using OS.File.

1 Like

Thanks for the feedback. I think I’ve solved the problem.

The reason I was using Application.storage was because I needed to save some values that were generated in an asynchronous function callback. Callback functions seem to have a very limited scope so I was having problems saving those results so other functions could use them. What I’ve done is written a routine that simulates Application.storage. It does not persist the data (I don’t know if Application.storage did or not - but I did not need it to anyway).

Here it is in case somebody else is trying to fix the same issue:

var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var main = {};

main = {
    topWin: Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getMostRecentWindow("navigator:browser"),  
    storage: {
        setItem: function setItem(key, value){
            if(typeof main.topWin.storage == "undefined") main.topWin.storage = {};
            if(key == null || key == "") return false;
            main.topWin.storage[key] = value;
            return true;
        },
        getItem: function getItem(key){
            if(key == null || key == "") return false;
            if(typeof main.topWin.storage[key] == "undefined") return false;
            let value = main.topWin.storage[key];
            return value;
        },
    }
}

Cool man thanks for sharing. Yeah if you dont need persistance definitely dont mess with file system. Global var is the way to go.