我在Firebase
项目上使用Android
进行数据存储,并使用Firebase Java API
来处理数据。我不确定我是否尽可能高效地进行此操作,并且我想要一些关于检索和格式化数据的最佳实践的建议。我的Firebase
存储库看起来像这样....
-POLLS
NUMPOLLS - 5
(pollskey) - NAME - Poll1
NUMELECTIONS - 2
ELECTIONS
(electionskey) - NAME - Election1
NUMNOMINATIONS - 2
NUMVOTERS - 2
NUMBERTOELECT - 1
VOTERS - (votesrkey) - NAME - Charles
NUMBER - (678) 333-4444
.
.
.
(voterskey) - ...
NOMINATIONS - (nominationskey) - NAME - Richard Nixon
NUMBEROFVOTES - 2
.
.
.
(nominationskey) - ...
.
.
.
(electionskey) - ...
.
.
.
(pollskey) - ...
所以,例如,我在这里试图从民意调查中获取所有数据,以列出民意调查名称,选举名称,候选人姓名和每次选举的投票数。我在主要活动的DataSnapshot
函数中得到了POLLS等级OnCreate()
,如此...
private static final Firebase polls = pollsFirebase.child("Polls");
protected void onCreate(Bundle savedInstanceState) {
polls.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot child : snapshot.getChildren()) {
if (!child.getName().equals("NumPolls")) {
createPollTableAndHeaders(child);
}
}
}
});
}
然后我继续在getValue()
上调用DataSnapshots
,并检查生成的HashMaps
...
private void createPollTableAndHeaders(DataSnapshot poll) {
String pollName = "";
int numPolls;
Object p = poll.getValue();
if (p instanceof HashMap) {
HashMap pollHash = (HashMap) p;
if (pollHash.containsKey("Name")) {
pollName = (String) pollHash.get("Name");
}
if (pollHash.containsKey("Elections")) {
HashMap election = (HashMap) pollHash.get("Elections");
Iterator electionIterator = election.values().iterator();
while (electionIterator.hasNext()) {
Object electionObj = electionIterator.next();
if (electionObj instanceof HashMap) {
HashMap electionHash = (HashMap) electionObj;
if (electionHash.containsKey("Name")) {
String electionName = (String) electionHash.get("Name");
}
}
};
}
}
这对于深入研究数据结构似乎是一种非常繁琐的方式,我想知道是否有更好的方法。
我在文档中看到过getValue(java.lang.Class<T> valueType)
方法,但由于我正在处理组合对象而不仅仅是基本类型的容器,因此无法在我的情况下使用它。函数如何知道要分配给模型对象的哪些成员变量的Firebase
数据?它是否与成员变量的Firebase
键名匹配,因此这些必须完全相同,区分大小写?如何处理Firebase
生成的关键名称,例如推送到List
时产生的关键名称?如何为组合对象构造模型对象?
答案 0 :(得分:18)
getValue(java.lang.Class valueType)
方法遵循与jackson对象映射库相同的规则(这是我们在内部使用的方法:http://wiki.fasterxml.com/JacksonInFiveMinutes)。因此,您的Java类必须具有默认构造函数(无参数)和要分配的属性的getter(https://www.firebase.com/docs/java-api/javadoc/com/firebase/client/DataSnapshot.html#getValue(java.lang.Class))。
简而言之,是的,Firebase中的键名必须与成员变量匹配。
有关使用复合对象(包括列表)的示例,请参阅AndroidDrawing。具体来说,Segment
类包含Point
个实例的列表。使用.push()
方法生成的数据列表有一个捕获。由于生成的密钥名称是字符串,因此它们在客户端中可以是唯一的,因此它们反序列化Map
而不是List
。但是,如果您迭代dataSnapshot.getChildren()
,它们将按顺序返回。
此外,如果您不想反序列化为HashMap,则可以在DataSnapshot上使用child()方法。例如:
String pollName = poll.child("Name").getValue(String.class);
DataSnapshot elections = poll.child("Elections");
for (DataSnapshot election : elections.getChildren()) {
String electionName = election.child("Name").getValue(String.class);
}
在此示例中,任何不存在的值都将返回为null
。
希望有所帮助!
答案 1 :(得分:1)
public T getValue(Class valueType)
1.该类必须具有不带参数的默认构造函数
2.该类必须为要分配的属性定义公共getter。没有公共getter的属性将在反序列化实例时设置为默认值
检查来自: this source它会帮助你