【问题标题】:Firebase won't save keys with null valuesFirebase 不会保存具有空值的键
【发布时间】:2014-12-20 13:49:38
【问题描述】:

我有一个类似的对象:

var _json = { "objects":[{
    "type":"path", "originX":"center", "originY":"center", "left":48.59, 
    "top":132.5, "width":64.5,"height":173, "fill":null,"stroke":"#3f7cc4", 
    "strokeWidth":12,"strokeDashArray":null
}]}

我使用 Firebase 将此对象保存为:

var myDataRef = new Firebase(<...>);
myDataRef.child("saved_projects").child(authData.uid).update({'P3': _json});

但是,当我使用 Firebase on 方法检索相同的值并获取值为:

snapshot.val()

我得到了对象,但是带有 null 值的键被删除了,即我只得到了:

{"objects":[ {"type":"path", "originX":"center", 
 "originY":"center","left":48.59, "top":132.5,"width":64.5, 
 "height":173, "stroke":"#3f7cc4","strokeWidth":12
}]}

这给我带来了一些奇怪的问题,因为我使用的是Fabric.js,它需要这些值。 请帮忙!

编辑/更新(黑客)

目前,我正在使用一种奇怪的 HACK,在将对象存储到 Firebase 之前,我将所有 null 值转换为 0。但我想知道一个更好的方法。

function recursivelyReplaceNullToZero(j) {
    for (var i in j){
        if (typeof j[i] === "object") {
            recursivelyReplaceNullToZero(j[i]);
        }
        if (j[i] === null) {
            j[i] = 0;
        }
    }
}
recursivelyReplaceNullToZero(_json);

【问题讨论】:

  • Firebase 会删除具有空值的节点,在这方面我们无能为力。 firebase.com/docs/web/api/firebase/set.html "为新值传递 null 等效于调用 remove();该位置或任何子位置的所有数据都将被删除。"
  • 这看起来像XY problem,您可能应该从您尝试解决的(有缺陷的?)用例开始。

标签: javascript object firebase


【解决方案1】:

目前我正在使用一个奇怪的 HACK,在将对象存储到 Firebase 之前,我将所有空值转换为 0。但我想知道更好的方法,拜托!

function recursivelyReplaceNullToZero(j) {
    for (var i in j){
        if (typeof j[i] === "object") {
            recursivelyReplaceNullToZero(j[i]);
        }
        if (j[i] === null) {
            j[i] = 0;
        }
    }
}
recursivelyReplaceNullToZero(_json);

【讨论】:

  • 我认为0是一个普通值,它可能会与null和实整数0冲突。所以,我建议将null递归转换为Null(字符串类型),并在getter函数上反向转换。
  • 是的,它会起作用,但你要确保没有冲突; IE:。您的应用程序中的任何变量都不能等于String(Null)。如果有的话;你应该设计逃生机制。
  • 其他官方的方法是让firebase删除值等于null的键。然后,在您的getter 中,您可以发现它。 if (!db.ref().child(path).value){ //do something} ;第二种情况,如果您获得父 ref,您应该通过 if (!value.hasOwnProperty(NullableKey)){//the key equal to null or not defined at all// doSomething} 之类的方法对键进行递归迭代
【解决方案2】:

fill 将是 string 类型,并且在 Firestore 中可以为空。 strokeDashArray 将是 array 类型,并且它们也可以包含空的 strings(以及其他数据类型)。请参阅下图,这是 Firestore 的屏幕截图。您对null 的看法是正确的,但它不会存储值为null 的属性。

请记住,Firestore 是一个文档数据库,并且没有架构 - 这意味着并非每个文档都需要包含所有字段(半结构化)。

因此,与其存储无价值的属性,不如简单地处理该属性在您的代码中可能不存在的可能性,例如,

if(doc.exists){
  if(doc.data().fill){
    // now you do what you want with the fill property
  } else {
    // there is no fill data
  }
}

【讨论】:

    【解决方案3】:

    这是预期的行为。 AFAIK json 系统就是这样工作的。

    您应该在代码集中为数据库中不存在的键设置空值。
    打个比方:想想前面的零 - 你不要写在数字前面。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-11
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2017-10-31
    • 1970-01-01
    相关资源
    最近更新 更多