我正在为我的Android应用程序使用Firebase数据库。我需要一个唯一的5位数代码,有效期为3天。为了解决这个问题,我在Firebase数据库中插入了所有可能的5位代码,其中每个条目的初始状态均为1
。所以结构看起来像这样:
codes: {
'abcde': {status:1},
'zhghs': {status:1}
.....
}
此codes
对象有将近500万个条目。我当时想在使用代码后将状态设置为2
。
我正在使用它从Firebase获取代码:
db.getReference("codes")
.orderByChild("status")
.limitToFirst(1)
.addListenerForSingleValueEvent { ..... }
我只需要1个代码,其状态为1
。上面的代码导致OutOfMemoryException
,因此我认为它正在尝试将所有数据加载到设备上。由于limitToFirst(1)
的限制,它不应该只是在设备端加载一个元素吗?
P.S。我已经尝试过Firebase FireStore。到目前为止,不允许每天导入大量JSON数据且每天的限制不超过20K。
编辑-我什至设置了db.setPersistenceEnabled(false)
确切的错误是:
Firebase数据库遇到OutOfMemoryError。您可能需要 减少同步到客户端的数据量。 java.lang.OutOfMemoryError:无法分配28701016字节 分配16777216个空闲字节和18MB直到OOM
答案 0 :(得分:1)
我只需要1个状态为1的代码即可。
在这种情况下,请将查询更改为:
db.getReference("codes")
.orderByChild("status")
.equalsTo(1)
.limitToFirst(1)
.addListenerForSingleValueEvent { ..... }
即使有这个约束,您也应该减少加载到内存中的数据量,因为似乎您将过多的数据强制到内存中。另外,您可以通过在Manifest.xml文件中设置android:largeHeap="true"
来设置较大的堆大小。通常此错误会消失。
您也可以在这篇密切相关的文章here中查看讨论。
正如@DougStevenson所说,这实际上不是解决OOM错误的推荐方法,但是正如我在@FrankvanPuffelen答案中所看到的那样,解决此问题的关键是添加最初缺少的".indexOn": "status"
。
答案 1 :(得分:1)
听起来您可能没有在status
属性上定义索引。在这种情况下,服务器无法为您进行排序/过滤,它将在客户端中完成。这意味着客户端必须读取所有数据并将其保存在内存中,从而解释了巨大的内存使用情况。
解决方案非常简单:在status
属性上定义一个索引。
{
"rules": {
"codes": {
".indexOn": "status"
}
}
}