Chrome.storage.local is undefined in Firefox

Hi. I’m debugging an add-on that makes use of chrome.storage.local to store JSON data.
I see from the add-on code that the data is stored using chrome.storage.local.set(...). It is also retrieved later in the code and the add-on works fine.

However, while debugging the add-on from the console tab, if I try to access or display the current content the console just returns ‘undefined’. I launch the debug toolbox via the about:debugging tab in Firefox version is 52.0.2 (32-bit).

For example,

>>> chrome.storage.local.get(null, s => console.log(s))
<-  undefined

Anyone got any idea why I can’t see the content?

The console shows undefined because that’s what get returns (meaning it returns “nothing”). The storage content is passed to the callback function you provided as an argument (as an arrow function) in the call of get.

What you should see is something like:

>>> chrome.storage.local.get(null, s => console.log(s))
<-  undefined
    Object {  }

Hi slosd,

Thanks for replying but I’m not sure what you’re trying to tell me. I think you’re just confirming what I’ve said…

I also tried

chrome.storage.local.get('myKey', function(data) {console.log(JSON.stringify(data))})

and in that case ‘undefined’ is returned too.

I wanted to make it clear that the undefined in your output

>>> chrome.storage.local.get(null, s => console.log(s))
<-  undefined

is the return value of get which is always undefined when you use it with a callback like you do.
If those two lines are the only ones in the console it means your callback is never called and console.log never actually prints anything.

Two things I can suggest:

  • Look for errors in the browser console (open with CTRL+SHIFT+J)
  • Try the browser entry-point and use the Promise returned by get:
    browser.storage.local.get().then(s => console.log(s), e => console.error(e))

Hi, From my pov… you can try to replace all ‘chrome’ keywords to ‘browser’ :slight_smile:

I don’t see there is still ‘chrome.storage’ api , but only ‘browser.storage’ which works fine for me… and I suppose all other similar case can be solved in that simple ‘replacing’ way.

Neither chrome.storage.local.get(...) nor browser.storage.local.get(...) return any data.

Both accept a callback as the last parameter and will asynchronously pass their data as an argument to that callback.

With browser.storage.local.get(...) you can omit the callback because it also returns a Promise. Promises are special ES6 language objects. Semantically they promise that some value will be avaiable in the future. There are two ways to get that future value: calling .then(...) on the promise and using the await keyword.

The latter only works form Firefox 52 onwards (and in current Chrome/Opera/Edge versions too), but allows for a semantic that looks as if the function actually returned a value:

const value = await browser.storage.local.get(...);

You can, however, only use await in functions that are themselfs marked as async, which makes them return a Promise to their actual return value (so if you call them and need that value, you’ll have to use an await in an async function again:

async function getRandomStorageValueAndAdd2() {
    const key = Math.random();
    const value = await browser.storage.local.get(key);
    return value + 2;
}

(async function main() {
    const value = getRandomStorageValueAndAdd2();
    console.log('useless value:', value);
})();

Thanks for the replies everyone. I’ll talk to the development team to urge them to switch to using browser.storage instead of chrome.storage. Is that backwards compatible?

I like the asynchronous feature. I had read another article that highlighted performance could be an issue while reading chrome.storage because it is done synchronously and done at the start of the add-on startup.

using browser.storage instead of chrome.storage. Is that backwards compatible?

It is exactly the same, except for the difference in the return value which I described above. It uses the same storage.


performance could be an issue while reading chrome.storage because it is done synchronously

Nope. chrome.storage is just as asynchronous as browser.storage. The article is talking about localStorage, which is an entirely different thing.

Just an observation - I have been trying storage.sync recently which is much the same.

The browser/chrome object difference is not obvious in MDN, especially if you start at the API pages. It’s mentioned under javascript APIs & chrome incompatibilities.

The APIs here and here don’t give examples - a beginner would be forgiven for not realising that you have to use either.

I actually implemented an addon recently using browser.storage and then thought it might work in Google Chrome - and had to convert it. I could have saved myself some work. (Yes - my fault. I should understand the basics better.)

And that storage.sync page could usefully mention that although compatible with Android v53 chrome.storage.sync doesn’t actually work - bug 1316442.