使用 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() 方法生成的数据列表有一个问题。由于生成的键名是字符串,因此它们在客户端之间是唯一的,因此它们反序列化 Maps 而不是 Lists。但是,如果您遍历 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 的问题

使用 KOTLIN 从 firebase 检索数据时出错

如何在flutter中将标记从firebase(真实数据库)检索到新的google maps api

将数据从 Firebase 检索到 tableview

Firebase 存储异步图像下载随机顺序