代码之家  ›  专栏  ›  技术社区  ›  Nick Cardoso

如何在Firebase实时数据库中加载/检索多对多关系

  •  -1
  • Nick Cardoso  · 技术社区  · 8 年前

    在我的Android项目中,我需要Firebase在检索多对多关系中的对象(组)时加载/检索我的“子对象”(用户名)列表,如下所示:

    App {
       "users" : {
            "user123jsbgkjwroi" : {
                "name" : "Mr Guy", 
                "groups" : {
                    "group567-alkfhhiuall_dajk" : true,
                    ...
                }
            }
        }
        "groups" : {
            "group567-alkfhhiuall_dajk" : {
                "name" : "My Group 1",
                "groupShortCode" : "567",
                "groupPassPhrase" : "ABC",
                "members" : {
                     "user123jsbgkjwroi" : {
                         "A": 2,
                         "B": 1,
                         "C": 33
                     },
                     ...    
                }
            }
        }
    } 
    

    我可能使我的生活变得更加困难,因为我是NoSQL新手,我的组对象使用用户作为映射键,而另一个对象包含列表(a、B、C)。如下所示:

    class Group {
        private String name;
        private Map<User, GroupItems> members;
    }
    

    当一个新用户加入组时,通过输入groupShortCode和groupPassPhrase,我需要加载整个组对象以及组的其他用户(成员)。

    但我不想递归地执行此操作(我宁愿获取尽可能少的文档-我不应该加载用户的其他组)。以下是我尝试过的:

    dbReference.child("groups").orderByChild("groupShortCode").equalTo(...)
               .addListenerForSingleValueEvent(new ValueEventListener() {
    
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            List<User> users = new ArrayList<>();
    
            //TODO: Here I need load each User, but it means tons of calls   
            Iterable<DataSnapshot> profileKeys = dataSnapshot.child("members").getChildren();
            for (DataSnapshot keySnapshot : profileKeys) {
                dbReference.child("users").child(keySnapshot.getKey())
                  .addListenerForSingleValueEvent( ... );
            }         
    
            //this constructor is because of the Object-to-Object Map so dataSnapshot.getValue() fails
            Group group = new Group(dataSnapshot, users);
            ...
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            ...
        }
    
    });
    

    我该如何正确、有效地完成这项工作!?

    推荐文章