Key values are stored in code.org's Firebase API. They are universal and accessible by any instance of a project. However, they are not copied when a project is remixed.
Basic recap on key value syntax:
var data = {"some_data":1234}; // can also be a string or number or array
var key = "some_key"; // must be a string
setKeyValue(key,data,function() {
console.log("success"); // value successfully stored
},function(e) {
throw e; // value failed to be stored
});
getKeyValue(key,function(d) {
console.log(d); // should print what was in the data variable
},function(e) {
throw e; // value failed to be fetched
});
Keys:
- Must be a string (other data types throw an error: "e.replace is not a function")
- Must not be empty (won't save, KEY_INVALID callback error)
- String must be < 698 chars long (won't save, empty callback error)
- String must not contain some characters:
- "$", "#", "[", "]", and "/" (will save under different key (all characters replaced by a "-"), KEY_RENAMED callback error)
- "\n", "\t", "\b", "\r", and other things (won't save, KEY_INVALID callback error)
- Fix by using
encodeURIComponent(key)
before getting/setting key values
Values:
- Can be any data type
- Objects cannot contain cyclical references (
data.data = data
will throw: "Maximum call stack size exceeded")
JSON.stringify(data).length <= 4096
(otherwise callback error "The value is too large. The maximum allowable size is 4096 bytes.")
- Saving more than 2 levels deep causes some information to be lost and converted to
undefined
{a:1,r:{b:2,r:{d:3}}}
will save as {a:1,r:{b:2,r:{d:undefined}}}
;
[1,[2,[3]]]
will save as [1,[2,[undefined]]]
;
- Fix by using
JSON.stringify(data)
before setting the key value and JSON.parse(retrived_data)
when getting the key value.
My advanced key value functions:
function getBigKeyValue(key,callback,failure) {
key = encodeURIComponent(key);
var value = "";
var n = 0;
var getNext = function() {
getKeyValue(key+"+"+n,function(part){
if (!part) {
if (value === "") {
callback();
return;
}
try {
value = JSON.parse(value);
callback(value);
} catch(e) {
if (typeof failure == 'function') failure(e);
else throw e;
}
return;
}
value += part;
n++;
getNext();
},function(e){
if (typeof failure == 'function') failure(e);
else throw e;
});
};
getNext();
}
function setBigKeyValue(key,value,success,failure) {
key = encodeURIComponent(key);
value = JSON.stringify(JSON.stringify(value));
value = value.substring(1,value.length-1);
var n = 0;
function setNext() {
var x = 4094;
if (value[4093] == "\\") x--;
var part = value.substring(0,x);
part = JSON.parse('"'+part+'"');
value = value.substring(x);
if (part.length == 0) {
if (typeof success == 'function') success();
return;
}
setKeyValue(key+"+"+n,part,setNext,function(e){
if (typeof failure == 'function') failure(e);
else throw e;
});
n++;
}
setNext();
}
Please note, that the above functions are very slow, so use the regular setKeyValue/getKeyValue when you can.
These functions should allow you to store data of any length/depth under keys of any name.
Additionally, when changing key values, use something similar to this:
function updateKeyValue(key,callback,failure) {
getKeyValue(key,function(v){
v = callback(v);
if (!v) return;
setKeyValue(key,v,function(){},failure);
},failure);
}
It helps prevent overwrites. However, be careful about using prompt()
inside the callback.