使用 Firebase Java API 检索/格式化数据的最佳方式
Posted
技术标签:
【中文标题】使用 Firebase Java API 检索/格式化数据的最佳方式【英文标题】:Best way to retrieve/format data using Firebase Java API 【发布时间】:2013-07-29 16:04:40 【问题描述】:我在android
项目上使用Firebase
存储数据,并使用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) - ...
因此,例如,在这里我试图从民意调查中获取所有数据,以列出民意调查名称、选举名称、候选人姓名和每次选举的票数。我在像这样的主要活动的OnCreate()
函数期间获得轮询级别DataSnapshot
...
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);
);
然后我通过在DataSnapshots
上连续调用getValue()
并检查生成的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
时生成的键名?如何为组合对象构造模型对象?
【问题讨论】:
【参考方案1】: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
s 而不是 List
s。但是,如果您遍历 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
。
希望有帮助!
【讨论】:
非常感谢格雷格。给我几个小时回家并尝试以这种方式实施。谢谢! 好吧,这就是我开始所需的一切。谢谢 Greg,感谢您的快速支持。 很抱歉提出一个旧线程,但是,我将 GeoFire 与 Firebase 一起使用,并且 Geolocation 类不提供默认构造函数。那么,我应该如何着手反序列化这种类?是否嵌入了任何解串器工厂?谢谢!【参考方案2】:public T getValue(Class valueType)
1.类必须有一个不带参数的默认构造函数
2. 类必须为要分配的属性定义公共 getter。反序列化实例时,没有公共 getter 的属性将设置为其默认值
从以下位置检查: this source对你有帮助
detail
【讨论】:
以上是关于使用 Firebase Java API 检索/格式化数据的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 java 从 Firebase 检索新添加的子项的父键
从 Firebase 检索 notificationTypes 的问题