具有多个密钥的Android Firebase查询

时间:2018-01-02 03:36:56

标签: android firebase firebase-realtime-database

这种问题已经被问到,有些人已经回答了。 但我有一些困惑,为什么我发布这个问题。在我阅读了Firebase文档"如何在here"中构建firebase中的数据后,我用Google搜索并尝试查询用户的组列表(对于几天仍然没有得到解决方案。)

enter image description here

假设我们已经拥有 / users / {$ user_id} 节点中用户参与的组ID ,我们希望获得组详细信息列表来自 / groups ,请注意分组ID列表。例如,类似下面的查询。

SELECT * FROM groups WHERE key = "techpioneers" AND key = "womentechmakers";

根据谷歌搜索结果和stackoverflow答案,Firebase不支持多个where子句。逐个迭代 / groups / {$ groud_id} 节点以获取组详细信息列表也不是一个好方法。

很抱歉。请帮助如何使用Firebase android SDK从Firebase查询具有多个密钥的此类数据列表。

1 个答案:

答案 0 :(得分:2)

Firebase实时数据库的一个缺点是它在数据结构方面缺乏灵活性。如果要执行查看不同数据节点的查询,则几乎总是需要对数据进行非规范化。这有利于

  1. 将您的数据分解为谨慎的块
  2. 更好地查询统计数据等
  3. 您不必下载大量嵌套数据
  4. 缺点是:

    1. 您的数据需要多个组合查询,例如group group1 name:"Best group" description: "The best group" group2: name:"An okay group" description: "A decent group" user user1 name: "User1" user2 name: "User2" group-by-user user1 group1: true group2: true user2 group2: true group-by-user`。
    2. 看起来有点复杂且不直观
    3. 回到你的问题: 给出以下表结构:

      //Get a reference to groups a user is in
             //get a reference
          DatabaseReference groupByUserRef = FirebaseDatabase.getInstance().getReference();
          //get a reference to the join table mentioned above
          groupByUserRef.child("group-by-user").child("user1").addValueEventListener(new ValueEventListener() {
              @Override
              public void onDataChange(DataSnapshot dataSnapshot) {
                  //This contains a list of group keys associated to the user;
                  Iterable<DataSnapshot> groupsByUser = dataSnapshot.getChildren();
                  //iterate through the list of group keys associated to the user
                  groupsByUser.forEach(groupDatasnapshot -> {
                      String groupId = groupDatasnapshot.getKey();
                      FirebaseDatabase groupReference;
                      DatabaseReference groupRef = FirebaseDatabase.getInstance().getReference();
      
                      //Once the key has been retrieved, do a search in the database to get the group
                      groupRef.child("group").child(groupId).addValueEventListener(new ValueEventListener() {
                          @Override
                          public void onDataChange(DataSnapshot dataSnapshot) {
                              //Here is where you will get the groups associated to the user.
                              Group group = dataSnapshot.getValue(Group.class);
                              //Add logic here ..
                          }
      
                          @Override
                          public void onCancelled(DatabaseError databaseError) {
      
                          }
                      });
                  });
              }
      
              @Override
              public void onCancelled(DatabaseError databaseError) {
      
              }
          });
      

      请注意我是如何创建一个新表,将用户与组关联,而不必将此信息放在用户表中。这可确保用户表仅用于基本的非关系用户信息。

      要在Java中查询,它看起来像下面的

      user

      修改 结束 如上所述,您可以看到这是一种非常复杂的方法。 这是Realtime数据库的缺点。如果您想确保不循环键,您可以选择以下选项。

      1. 不要对您的数据进行非规范化,并将组信息直接放在hasRole('ADMIN')表中。当您的组信息增长时(其中一些您不需要),您必须提取大量数据。
      2. 使用firebase云端防火墙 - 他们已设法解决此问题