Android - 从Firebase检索数据

时间:2017-10-13 14:55:58

标签: android firebase firebase-realtime-database

我正在开发一个Android应用程序,年龄较大的孩子可以捡到年幼的孩子并步行上学。通过该应用程序,经过身份验证(电子邮件和密码)的小孩可以在三个地址之间进行选择以获取。截至目前,我的实时数据库看起来像这样:

enter image description here

我想检索不同的地址和选择地址的用户。我想我必须使用recyclerview来获取数据,但我不确定是否可以使用我的数据库结构。

enter image description here

2 个答案:

答案 0 :(得分:2)

使用FirebaseUI database package可以轻松地将Firebase实时数据库中的数据绑定到应用的用户界面。具体来说,using FirebaseUI with indexed data适用于您当前的数据库结构。

例如,您使用类似于:

的内容
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
// dataRef - the Firebase location to watch for data changes. Each key found at 
//           keyRef's location represents a list item.

Query keyQuery = FirebaseDatabase.getInstance().getReference("/Addresses/Street 10/users");
DatabaseReference dataRef = FirebaseDatabase.getInstance().getReference("/User");

FirebaseRecyclerOptions<User> options = new FirebaseRecyclerOptions.Builder<User>()
        .setIndexedQuery(keyQuery, dataRef, User.class)
        .build();

您的用户类位于:

public class User {
    private String username;

    public User() {}

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    // ...
}

然后,您可以将上面创建的options变量用于create a FirebaseRecyclerAdapter instance,然后在其上调用startListening() *。

以这种方式使用FirebaseUI会自动处理/Addresses/Street 10/users/User节点下的密钥匹配。

* FirebaseUI版本2.x使用FirebaseIndexRecyclerAdapter代替并自动开始收听,因此不需要startListening()来电。以上示例适用于3.0版,请参阅FirebaseUI 3.0 upgrade guide

答案 1 :(得分:2)

my previous answer开始,这个应该满足您创建所有地址及其相关用户的列表的要求,这可能更接近您正在寻找的地址。

同样,您可以使用FirebaseUI database package来简化RecyclerView的创建。

您需要开始对数据进行非规范化,因此您的数据结构还应包含地址节点中的用户名:

{
  "Addresses" : {
    "Street 10" : {
      "name" : "Street 10",
      "users" : {
        "VAzdMWafK6cyhmJnOI4br5xiQg93" : "John"
      }
    }
  },
  "User" : {
    "VAzdMWafK6cyhmJnOI4br5xiQg93" : {
      "username" : "John",
      "address" : "Street 10"
    }
  }
}

注意:您只需要将用户ID添加到他们选择的地址(如果他们更改选择,则删除节点),因此不要将"VAzdMWafK6cyhmJnOI4br5xiQg93" : false用于用户未选择的地址,因为这可能引起混淆。

然后你可以使用:

Query query = FirebaseDatabase.getInstance().getReference("/Addresses");

FirebaseRecyclerOptions<Address> options = new FirebaseRecyclerOptions.Builder<Address>()
        .setQuery(query, Address.class)
        .build();

Address类似于:

public class Address {
    private String name;
    private Map<String, String> users;

    public Address() {}

    public Map<String, String> getUsers() {
        return this.users;
    }

    // ...
}

来自options变量的create a FirebaseRecyclerAdapter instance。然后,当绑定适配器中的视图时,您可以访问users映射以列出已选择此地址的每个用户,而无需不必要地加载整个User对象。

此模式称为denormalization,是使用NoSQL数据库(如Firebase实时数据库)时的建议方法。这方面的主要缺点是数据重复:例如,当用户更改其选定的地址时,您需要更改:

  • 用户下的address值和
  • 地址下的users列表。

同样,如果允许用户更改其用户名,则需要在其选择的地址和用户节点下更新用户名。

有关处理此问题的详细信息,请参阅this answer which explains a number of methods(虽然这些示例都在JavaScript中,但前提仍然适用)。