Simpl-storage problem

I want to store some data in the addon SDK.

var ss = require("sdk/simple-storage");

ss.storage.myArray = [1,2,1,3,4,5];
ss.storage.myString="Hi";

I use JPM. To run the code, I navigate to the profile where the extension is stored in. In Windows:
C:\Users\myuser\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]\extensions\storage

Then, I run this command: jpm run --no-copy --profile C:\Users\myuser\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]

But what I get as a result is an empty new browser window with lots of lines as the this:

1494868910707   DeferredSave.extensions.json    DEBUG   Save changes
1494868910708   DeferredSave.extensions.json    DEBUG   Save changes
1494868910710   addons.manager  DEBUG   Registering startup change 'changed' for @storage
1494868910718   addons.xpi      DEBUG   Loading bootstrap scope from C:\Users\myuser\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]\extensions\@storage.xpi
1494868910769   addons.xpi      DEBUG   Calling bootstrap method install on @storage version 0.0.1
1494868910769   addons.xpi-utils        DEBUG   Make addon app-profile:@storage visible
1494868910770   DeferredSave.extensions.json    DEBUG   Save changes
1494868910770   addons.xpi-utils        DEBUG   Make addon app-system-defaults:aushelper@mozilla.org visible
1494868910771   DeferredSave.extensions.json    DEBUG   Save changes

Can you clarify how can I use simpl-storage to store some data permanently in the Addon?

I navigated to extensions directory inside my profile and found this file: @storage.xpi but I tried to open it and its content is unreadable!

What exactly do you think jpm run --no-copy --profile C:\Users\e\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]\extension\storage should do?

Here is the description of

-p, --profile <path>     Path or name of Firefox profile to use.

I doubt that you have a valid profile in C:\Users\e\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]\extension\storage. Do you mean C:\Users\e\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]?

It was a typeo. Yes. I mean:
C:\Users\myuser\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]

I navigated to that path: C:\Users\myuser\AppData\Roaming\Mozilla\Firefox\Profiles\[myprofile]\extension\storage (which is the extension directory which is named: storage) before I run the JPM. What I do not know is what should I expect after running that piece of code? where can I find the data? how to retrieve them in my addon? in SDK please as I am working on SDK at the mean time in a legacy extension for local use.

This should work and demonstrate how it works:

const { storage, } = require("sdk/simple-storage");
let userId = strage.userId; // read the id
if (!userId) { userId = storage.userId = Math.random(); } // write it if not set, should only happen once (or after it was deleted)

Thanks. I got some issues:

  1. Whay did you add a comma in: const { storage, } ?
  2. When I run the code using: jpm run -b "[Firefox Developer Edition Path]", the previous values are not saved and I got new values every run.
  3. When I run it using: jpm run --no-copy --profile "C:\[myProfilepath]", a new browser window opens and I get a continuous debugging data on the cmd window and until I close the browser window.
  4. When I run it using: jpm run --no-copy --profile "C:\[myProfilepath]" -b "[Firefox Developer Edition Path]", I get same thing as before.

the bottom line: what is the proper command line to run it in jpm without losing the data? I understand that I need to use --no-copy --profile but that does not work either. I am not sure how to write the paths? with double quotations or not? and shall I sue -b “[Firefox Developer Edition Path]”` or not?

  1. The coma is optional, as JavaScript allows trailing commas in all comma separated lists, making them comma terminated lists. The reason why I set it is, that it is easier to copy/paste, move or append elements or lines if you use terminators after every element. Foe example, if you have a declaration like
obj = {
    one: 1,
    two: 2
}

and decide to add an element, you will have to change the two: 2 line:

obj = {
    one: 1,
    two: 2,
    three: 3
}

which will show up as one removed and two added lines. With tailing commas that doesn’t happen. As part of a consistent coding style, I decided to always use tailing commas (unless I work with other people who decided to do it differently).

  1. The values are probably saved, but once you close the browser instance, the entire temporary profile will be deleted.

I’d suggest you do this (assuming your cmd is in your extensions code folder and that is placed inside some kind of debug or projects folder):

Create a (persistent) Firefox debug profile:

mkdir …\ff-debug

Start the profile once:

jpm run -b “C:\Program Files\Firefox Developer Edition\firefox.exe” -p …\ff-debug --no-copy

Then go to about:config and toggle xpinstall.signatures.required to true.
Quit Firefox.

Now, whenever you want to work with that persistent profile, repeat

jpm run -b “C:\Program Files\Firefox Developer Edition\firefox.exe” -p …\ff-debug --no-copy

If you only want to acces the previous data but don’t want to persist changes you make, omit the --no-copy .


double quotations or not?

In command likes, the space character separates the arguments. If you want a single argument that contains spaces, you have to enclose it in ". So you can put quotes around every single argument, but you only need to do it for those that contain spaces.

Here is my command to run the simple-storage example that is stored in a directory inside profile-1

[path-to-the-extension-directory-under-profile-1]>jpm run -b "C:\Program Files\Firefox Developer Edition\firefox.exe" -p "[path-to-debug-profile-that-i-created]" --no-copy

The result is a lot of lines that I really do not get what they are for. Then a lot of files and folders gets in the debug profile.

Can you help me please run a simple-storage example? This is a sample code:

var ss = require("sdk/simple-storage");
if (!ss.storage.pages) //to avoid zeroing the array
    ss.storage.pages = [];

require("sdk/tabs").on("ready", function(tab) {
  ss.storage.pages.push(tab.url);
  console.log("inside on function");
});

require("sdk/ui/button/action").ActionButton({
  id: "read",
  label: "Read",
  icon: "./icon-16",
  onClick: function() {
    console.log(ss.storage.pages);
  }
});

The way I proposed it generally works. If it doesn’t for you, then I need details. That includes the exact console input and output.

Also, if you want to test the simple-storage, you should use only that API, nothing else. You should dump all that action button and tab stuff. Go with my code. Don’t try anything fancy until you observe a persistent userId.

Here is the command:
C:\Users\[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\up1vci1q.development\extensions\storage>jpm run -b "C:\Program Files (x86)\Firefox Developer Edition\firefox" --no-copy --profile "C:\Users\[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\debug2"

The output is a continuous long debugging data. It does not stop unless I close the browser developer edition window that is opened with the run. I will select output from the start and end (it is too long to be posted here). Hopefully you can help:

JPM [info] Starting jpm run on storage
JPM [info] Using provided profile:
JPM [info]     C:\Users\[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\debug2
1494964890134   addons.manager  DEBUG   Application has been upgraded
1494964890161   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/XPIProvider.jsm: ["XPIProvider"]
1494964890163   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/LightweightThemeManager.jsm: ["LightweightThemeManager"]
1494964890166   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/GMPProvider.jsm
1494964890167   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/PluginProvider.jsm
1494964890168   addons.manager  DEBUG   Starting provider: XPIProvider
1494964890169   addons.xpi      DEBUG   startup
1494964890170   addons.xpi      INFO    Mapping @storage to C:\Users\[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\debug2\extensions\@storage.xpi
1494964890170   addons.xpi      INFO    Removing all system add-on upgrades.
1494964890170   addons.xpi      INFO    SystemAddonInstallLocation directory is missing

Then at the end:

1494964891177   DeferredSave.extensions.json    DEBUG   Write succeeded
1494964891177   addons.xpi-utils        DEBUG   XPI Database saved, setting schema version preference to 19
1494964891177   DeferredSave.extensions.json    DEBUG   Starting timer
1494964891196   addons.repository       DEBUG   No addons.json found.
1494964891196   DeferredSave.addons.json        DEBUG   Save changes
1494964891201   DeferredSave.addons.json        DEBUG   Starting timer
1494964891230   addons.manager  DEBUG   Starting provider: PreviousExperimentProvider
1494964891230   addons.manager  DEBUG   Registering shutdown blocker for PreviousExperimentProvider
1494964891230   addons.manager  DEBUG   Provider finished startup: PreviousExperimentProvider
1494964891234   DeferredSave.extensions.json    DEBUG   Starting write
1494964891300   DeferredSave.addons.json        DEBUG   Starting write
1494964891308   DeferredSave.extensions.json    DEBUG   Write succeeded
1494964891315   DeferredSave.addons.json        DEBUG   Write succeeded
1494964896089   addons.xpi      DEBUG   Calling bootstrap method shutdown on webcompat@mozilla.org version 1.1
1494964896090   addons.xpi      DEBUG   Calling bootstrap method shutdown on shield-recipe-client@mozilla.org version 1.0.0
1494964896093   addons.xpi      DEBUG   Calling bootstrap method shutdown on presentation@mozilla.org version 1.0.0
1494964896095   addons.xpi      DEBUG   Calling bootstrap method shutdown on formautofill@mozilla.org version 1.0
1494964896096   addons.xpi      DEBUG   Calling bootstrap method shutdown on flyweb@mozilla.org version 1.0.0
1494964896096   addons.xpi      DEBUG   Calling bootstrap method shutdown on firefox@getpocket.com version 1.0.5
1494964896097   addons.xpi      DEBUG   Calling bootstrap method shutdown on e10srollout@mozilla.org version 1.15
1494964896097   addons.xpi      DEBUG   Calling bootstrap method shutdown on aushelper@mozilla.org version 2.0
1494964896328   addons.manager  DEBUG   shutdown
1494964896329   addons.manager  DEBUG   Calling shutdown blocker for XPIProvider
1494964896329   addons.xpi      DEBUG   shutdown
1494964896329   addons.xpi-utils        DEBUG   Updating add-on states
1494964896332   addons.xpi-utils        DEBUG   Writing add-ons list
1494964896334   addons.xpi-utils        DEBUG   shutdown
1494964896335   addons.manager  DEBUG   Calling shutdown blocker for LightweightThemeManager
1494964896335   addons.manager  DEBUG   Calling shutdown blocker for GMPProvider
1494964896337   addons.manager  DEBUG   Calling shutdown blocker for PluginProvider
1494964896338   addons.manager  DEBUG   Calling shutdown blocker for <unnamed-provider>
1494964896340   addons.manager  DEBUG   Calling shutdown blocker for PreviousExperimentProvider
1494964896344   addons.xpi      DEBUG   Notifying XPI shutdown observers
1494964896350   addons.manager  DEBUG   Async provider shutdown done

Note that the debugging messages do not stop until I close the browser.

You might prepend your console.log messages with some asterisks (e.g. *****) or another marker so you can easily find them in the console noise.

I did. Any log from my program does not appear. There is something wrong. However, if I omit this part from the command: --no-copy --profile "C:\Users\[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\debug2", the program seems to run perfectly, but each time I get different useId (reference to this example:

const { storage, } = require("sdk/simple-storage");
let userId = storage.userId; // read the id
if (!userId) { userId = storage.userId = Math.random(); } // write it if not set, should only happen once (or after it was deleted) 
console.log(userId);

Die you do this?:

Start the profile once:
jpm run -b "C:\Program Files\Firefox Developer Edition\firefox.exe" -p ..\ff-debug --no-copy
Then go to about:config and toggle xpinstall.signatures.required to true.
Quit Firefox.

Your extension will be disabled otherwise. You can check that in the add-on manager.


C:\Users[myUser]\AppData\Roaming\Mozilla\Firefox\Profiles\up1vci1q.development\extensions\storage

Is that where you are developing your add-on? That is not a good location for it.

Where do you recommend me to create my own extension directory?

I’d recomend a short path without spacers that doesn’t conflict with anything else.
On a Windows system with a single active user, I use C:\dev\ for most my projects. Some IDEs will put their stuff in a subdirectory of the Documents folder by default.

But wherever you put it, make regular backups (I use git with GitHub as remote). Nothing is more stupid than loosing code because you had no backup.

I am not sure whether you mean I should set the xpinstall.signatures.required to true or false?
When I set it to true, I got a warning that says:
storage could not be verified for use in Firefox Developer Edition and has been disabled
I see the Addon in the about:addons but with this warning. When I set xpinstall.signatures.required to off, I can not run the addon. It just print debugging messages until I closes the browser.

Here is my command after using a shorter path. I created a directory for the developing addon called storage which is under the c:\dev directory:
C:\dev\storage>jpm run -b "C:\Program Files (x86)\Firefox Developer Edition\firefox" --no-copy --profile "C:\dev"

It is not a problem that I do not have a profile in advance called dev as it is created after I run the command.

I am using Firefox Developer Edition version 54, and JPM version 1.3.1 in Windows.

storage could not be verified for use in Firefox Developer Edition and has been disabled

That’s a very common message. You schools be able to find out what it means and a solution with Google (or whatever search engine you prefer).

–profile “C:\dev”

You should create a subdirectory for that, to avoid a mess and file conflicts.

Of course I know that because the addon is not signed yet. But you said I should set the xpinstall.signatures.required to true which makes me wonder if this is a typo? I believe it should be false so that the browser does not require signed addon.

However, the problem is that even when false is set, I just get debugging messages.

What is the best method for storing permanent data ? For example, user supplied data?

My Bad. False is what you want. True would be the default.

I will try a complete example the next time I am at my computer.

I hope you try to replicate this in your side and let me know what is the issue.

I run this code which resides in: C:\dev\extensions\storage

var ss = require("sdk/simple-storage");
ss.storage.myText="***********************data****************";

console.log("********************************");
console.log(ss.storage.myText);
console.log("********************************");

I make sure that the signature required key is set to false in the browser.

Then I run the code using this command:

jpm run -b "C:\Program Files (x86)\Firefox Developer Edition\firefox" --no-copy --profile "C:\dev"

Result: lines of debugging starts with:

JPM [info] Starting jpm run on storage
JPM [info] Using provided profile:
JPM [info]     C:\dev
1495131242137   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/XPIProvider.jsm: ["XPIProvider"]
1495131242139   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/LightweightThemeManager.jsm: ["LightweightThemeManager"]
1495131242142   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/GMPProvider.jsm
1495131242145   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/PluginProvider.jsm
1495131242146   addons.manager  DEBUG   Starting provider: XPIProvider
1495131242146   addons.xpi      DEBUG   startup
1495131242148   addons.xpi      INFO    Mapping @storage to C:\dev\extensions\@storage.xpi

Then I close the browser. I find a file .xpi added in the extension directory.

When I try to run the code normally without the --no-profile -p “C:\dev” I get the output in the console. But I do not know if the data has stored or not? where can I check? also, I still need to run it in the proper way where I do not los the old data.