如果我将数据插入firebase中的node/a/0
。
结果会将a
视为数组a[0]
。
同样,如果我在node/a/1
中设置数据,第一个数组将变为空
"a" : [ null, {
"-J-22j_Mb59l0Ws0H9xc" : {
"name" : "chok wee ching"
}
} ]
但如果node/a/2
"a" : {
"2" : {
"-J-25xjEXUqcpsC-5LOE" : {
"name" : "chok wee ching"
}
}
}
我的猜测,firebase会自动将单个0和1视为一个数组。 我该如何防止这种情况?
答案 0 :(得分:7)
Firebase没有对数组的本机支持。如果存储数组,它实际上存储为“对象”,整数作为键名。
但是,为了帮助人们在Firebase中存储数组,当您调用.val()或使用REST api从Firebase读取数据时,如果数据看起来像一样,Firebase将会将其渲染为数组。
特别是,如果所有键都是整数,并且对象中超过一半的键与对象中的最大键具有非空值,则Firebase会将其渲染为数组。这是您遇到的启发式的后半部分。您的第二个示例仅为2设置值,而不是0和1,因此不到一半的键具有值,因此Firebase将其呈现为对象。
您目前无法更改或阻止此行为(虽然这是一个常见的混淆源,因此我们可能会在未来对此进行一些调整)。但是,一旦理解了行为,通常很容易处理。如果您需要进一步的帮助,也许您可以扩展您的问题来解释您需要完成什么以及此行为如何阻止它。
答案 1 :(得分:1)
我遇到了同样的问题,但实际上想在Swift中使用数字键数组([Int:AnyObject]
)。我写了这个函数,以确保总是有一个数组(没有空值):
func forceArray(from: Any?) -> [Int:AnyObject] {
var returnArray = [Int:AnyObject]()
if let array = from as? [String:AnyObject] {
for (key, value) in array {
if let key = Int(key) {
returnArray[key] = value
}
}
return returnArray
}
if let array = from as? [AnyObject] {
for (key, value) in array.enumerated() {
if !(value is NSNull) {
returnArray[key] = value
}
}
return returnArray
}
return returnArray
}
结果:
["0":1, "1":2]
变为:[0:1, 1:2]
{"0":1, "6":2}
变为:[0:1, 6:2]
["0":1, "1": null, "2":2]
变为:[0:1, 2:2]
希望这对某人有帮助!
答案 2 :(得分:1)
是的,将密钥存储为0和1会产生问题,因为Firebase会认为它是一个数组。
我的简单解决方法是使用:
String(format:"%03d", intValue)
这样生成的密钥将是" 000"和" 001",并且可以轻松地将它们转换回Int。
答案 3 :(得分:1)
REST API的解决方法:添加一个无意义的过滤器,例如orderBy="$.key"&startAt="0"
,它实际上过滤掉所有带负片的项目):https://workaround-arrays-bagohack.firebaseio.com/matchesHeuristic.json?orderBy=%22 $ key%22& startAt =%220%22& print =漂亮
这是Firebase的已知和不幸(恕我直言)行为,记录在其支持知识库的深处。引自Best Practices: Arrays in Firebase:
Firebase没有对数组的本机支持。如果你存储一个数组,它 真的存储为“对象”,整数作为键名。
// we send this
['hello', 'world']
// Firebase stores this
{0:'hello', 1: 'world'}
但是,要帮助那些存储阵列的人 在Firebase中,当您调用
.val()
或使用REST api读取数据时,如果 数据看起来像一个数组,Firebase会将其渲染为数组。特别是,*如果所有键都是整数,则超过一半 0和对象中的最大键之间的键具有非空 值,然后Firebase将其呈现为数组。后一部分是 重要的是要记住。
您目前无法更改或阻止此行为。希望 了解它将使人们更容易看到一个人能做什么,不能做什么 存储类似数据时。
所以我为你设置了一个小的repro。 原始数据:
{
"matchesHeuristic": {
"1": {
"id": "foo",
"value": "bar"
},
"2": {
"id": "w",
"value": "tf"
}
},
"notMatchesHeuristic": {
"1": {
"id": "foo",
"value": "bar"
},
"365": {
"id": "w",
"value": "tf"
}
}
}
由Firebase REST API返回:https://workaround-arrays-bagohack.firebaseio.com/.json?print=pretty
{
"matchesHeuristic" : [ null, {
"id" : "foo",
"value" : "bar"
}, {
"id" : "w",
"value" : "tf"
} ],
"notMatchesHeuristic" : {
"1" : {
"id" : "foo",
"value" : "bar"
},
"365" : {
"id" : "w",
"value" : "tf"
}
}
}
正如您所见,matchesHeuristic
对象被转换为索引为0的空值的数组(因为它与Firebase文档中定义的启发式匹配),而notMatchesHeuristic
保持不变。如果你有像我们这样的动态数据,这尤其“好” - 所以我们不知道如果它与heauristic匹配还是不匹配的运行时。
然而,这部分文档似乎并不成立:
您目前无法更改或阻止此行为。希望 了解它将使人们更容易看到一个人能做什么,不能做什么 存储类似数据时。
您实际上可以通过请求按键搜索的项目来解决此问题,所以
orderBy="$.key"&startAt="0"
实际过滤掉所有带负片的项目) : {"1":{"id":"foo","value":"bar"},"2":{"id":"w","value":"tf"}}