Chrome "get" storage API returns Object value even if not present

120 views
Skip to first unread message

Jan Riechers

unread,
Nov 14, 2024, 8:24:56 AMNov 14
to Chromium Extensions
Hello,

I want to request, by using a helper set/get function[1], Object based values of the "storage.local.get" - but the culprit (I have not yet found a useful workaround) - always returns the "request Object with request keys/values" if nothing is found.

This does, for my understanding, not make much sense. If I request some information of the "storage" - I want to either get the value or nothing at all if nothing is found/matching.

The helper "get" function can be found here:
[1] https://github.com/jrie/flagCookies/blob/aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L37

and here and example on how it is used:
https://github.com/jrie/flagCookies/blob/aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L757

Maybe I am missing something, but it is a big blocker for me to optimize the extension/add on - which heavy relies on storage data.

Any help is appreciated.

Oliver Dunk

unread,
Nov 14, 2024, 8:53:34 AMNov 14
to Jan Riechers, Chromium Extensions
Hi Jan,

You're right that you will always receive an object as a response to any calls. In addition, the StorageArea interface and the get() method have a few different signatures:
  • If you just request a key, e.g `await chrome.storage.local.get("testing")`, the result will only include the key if present.
  • If you request with a value, e.g `await chrome.storage.local.get({"testing": 5})`, the value is used as a default if the key isn't present.
So you should be able to use the top option to determine if a key exists.

If you really want to get null / undefined as the return value, this isn't something which is possible today. I don't think that should be a significant issue though - if you disagree it would be interesting to hear more. Something to note is that there's always a balance we try to find between providing ergonomic APIs and not implementing everything if something is easy to write in your own code using existing building blocks.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/67492510-9adb-476e-b239-0c5b31044ecan%40chromium.org.

Max Nikulin

unread,
Nov 14, 2024, 11:34:57 AMNov 14
to chromium-...@chromium.org
On 14/11/2024 20:24, Jan Riechers wrote:
> I want to request, by using a helper set/get function[1], Object based
> values of the "storage.local.get" - but the culprit (I have not yet
> found a useful workaround) - always returns the "request Object with
> request keys/values" if nothing is found.
>
> This does, for my understanding, not make much sense

My guess is that the API method is optimized for getting multiple keys
at once and so minimizing number of async calls.

> If I request some
> information of the "storage" - I want to either get the value or nothing
> at all if nothing is found/matching.
>
> The helper "get" function can be found here:
> https://github.com/jrie/flagCookies/blob/aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L37

For me it is not clear what you are trying to achieve, perhaps I just
have not spent enough time in attempts to figure out your data scheme.
Certainly you are fetching values one by one instead of requesting the
whole bunch.

At first glance the following simple wrapper matches your description

async function inefficientGet(key, defaultValue) {
const { [key]: retval = defaultValue }
= await chrome.storage.local.get(key);
return retval;
}

Jan

unread,
Nov 14, 2024, 3:43:23 PMNov 14
to chromium-...@chromium.org
On 14.11.24 17:34, Max Nikulin wrote:
> On 14/11/2024 20:24, Jan Riechers wrote:
>> I want to request, by using a helper set/get function[1], Object based
>> values of the "storage.local.get" - but the culprit (I have not yet
>> found a useful workaround) - always returns the "request Object with
>> request keys/values" if nothing is found.
>>
>> This does, for my understanding, not make much sense
>
> My guess is that the API method is optimized for getting multiple keys
> at once and so minimizing number of async calls.
>

This might reduce calls yes - but I store a lot of custom settings. At
the bottom of this email, there is a example json output.

>> If I request some information of the "storage" - I want to either get
>> the value or nothing at all if nothing is found/matching.
>>
>> The helper "get" function can be found here:
>> https://github.com/jrie/flagCookies/blob/
>> aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L37
>
> For me it is not clear what you are trying to achieve, perhaps I just
> have not spent enough time in attempts to figure out your data scheme.
> Certainly you are fetching values one by one instead of requesting the
> whole bunch.
>
> At first glance the following simple wrapper matches your description
>
> async function inefficientGet(key, defaultValue) {
>     const { [key]: retval = defaultValue }
>         = await chrome.storage.local.get(key);
>     return retval;
> }
>

Yes, this might be inefficient at first glance, but retrieving a exact
"Object with keys" - allows to pull out only needed data for a
particular case.

Not "single string" value which returns "null" or "undefined".

----------

Here is a JSON of the output of the settings - basically everything that
is stored here is for "google.com" (cookies) only. Just imagine you have
50 more domains or tabs and for every little "data" (cookie) change, the
whole storage.local is pulled out - which I do right now and it slows
down dramatically.

Sample data:

{
"default": {
"www.google.com": {
".google.com": {
"SIDCC": true,
"__Secure-1PSIDCC": true,
"__Secure-1PSIDTS": false,
"__Secure-3PAPISID": false,
"__Secure-3PSIDCC": false
},
".support.google.com": {
"_ga_H30R9PNQFN": true
},
"accounts.google.com": {
"ACCOUNT_CHOOSER": true,
"LSID": false,
"__Host-1PLSID": false,
"__Host-3PLSID": true
}
}
},
"flagCookies_accountMode": {
"default": {
"www.google.com": true
}
},
"flagCookies_autoFlag": {
"default": {
"www.google.com": true
}
},
"flagCookies_logged": {
"default": {
"www.google.com": {
".chromewebstore.google.com": {
"_ga": true,
"_ga_KHZNC1Q6K0": true
},
".google.com": {
"AEC": true,
"APISID": true,
"HSID": true,
"NID": true,
"SAPISID": true,
"SID": true,
"SIDCC": true,
"SOCS": true,
"SSID": true,
"__Secure-1PAPISID": true,
"__Secure-1PSID": true,
"__Secure-1PSIDCC": true,
"__Secure-1PSIDTS": true,
"__Secure-3PAPISID": true,
"__Secure-3PSID": true,
"__Secure-3PSIDCC": true,
"__Secure-3PSIDTS": true,
"__Secure-ENID": true
},
"chromewebstore.google.com": {
"OSID": true
}
}
}
}
}

Jan

unread,
Nov 14, 2024, 3:59:04 PMNov 14
to Oliver Dunk, Chromium Extensions
On 14.11.24 14:52, Oliver Dunk wrote:
> Hi Jan,
>
> You're right that you will always receive an object as a response to any
> calls. In addition, the StorageArea interface and the get() method have
> a few different signatures:
>
> * If you just request a key, e.g `await
> chrome.storage.local.get("testing")`, the result will only include
> the key if present.
> * If you request with a value, e.g `await
> chrome.storage.local.get({"testing": 5})`, the value is used as a
> default if the key isn't present.
>
> So you should be able to use the top option to determine if a key exists.
>

Regarding the second option, requesting a object - maybe I miss
something out..

I need to check if a key is present and return its values if so, if the
key is not present, nothing should be returned.


> If you really want to get null / undefined as the return value, this
> isn't something which is possible today. I don't think that should be a
> significant issue though - if you disagree it would be interesting to
> hear more.
>
Have a look at this function, especially line 43 and 45:
https://github.com/jrie/flagCookies/blob/aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L37

And here is, where the data is requested:
https://github.com/jrie/flagCookies/blob/aa31a2a06f0f9bfe54de27d199aa360003468529/cookies.js#L758

--------------------

I mentioned in another post on this list, in this topic:
Here is a JSON of the output of the settings - basically everything that
is stored here is for "google.com" (cookies with names and boolean) only
which are managed inside the extension.


Explanation what the line 758 actually should do, but not doing at all
with this code:

[L758] const flagCookiesLoggedDomain = await getStoreValue(contextName,
'flagCookies_logged', strippedRootDomain);


"strippedRootDomain" <== is "www.google.com".



Check for:
"flagCookies_logged" -> "default" -> "www.google.com"

and return the data.



Here is the sample data:

Max Nikulin

unread,
Nov 15, 2024, 11:37:07 AMNov 15
to chromium-...@chromium.org
On 15/11/2024 03:42, Jan wrote:
> On 14.11.24 17:34, Max Nikulin wrote:
>> My guess is that the API method is optimized for getting multiple keys
>> at once and so minimizing number of async calls.
>
> This might reduce calls yes - but I store a lot of custom settings. At
> the bottom of this email, there is a example json output.

To be clear, for the provided data structure by optimizing I mean

chrome.storage.local.get([
contextName,
"flagCookies_accountMode",
"flagCookies_autoFlag",
"flagCookies_logged"
]);


> Yes, this might be inefficient at first glance, but retrieving a exact
> "Object with keys" - allows to pull out only needed data for a
> particular case.

I still feel that I can not figure out what is your goal. If you are
trying to minimize amount of data fetched for current domain then I
would consider another data structure with keys combining context name
and domain:

{
"ctx-origin|default|www.google.com": {
"cookie": {
".google.com": {
"SIDCC": true,
"__Secure-1PSIDCC": true,
"__Secure-1PSIDTS": false,
"__Secure-3PAPISID": false,
"__Secure-3PSIDCC": false
},
".support.google.com": {
"_ga_H30R9PNQFN": true
},
"accounts.google.com": {
"ACCOUNT_CHOOSER": true,
"LSID": false,
"__Host-1PLSID": false,
"__Host-3PLSID": true
}
},
"flagCookies_accountMode": true,
"flagCookies_autoFlag": true,
"flagCookies_logged": {

Oliver Dunk

unread,
Nov 18, 2024, 9:32:04 AM (14 days ago) Nov 18
to Max Nikulin, chromium-...@chromium.org
I'm afraid that I have similar confusion to Max.

If you're able to share more about what your concern is, we might be able to help.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
Reply all
Reply to author
Forward
0 new messages