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

Posted

技术标签:

【中文标题】如何在 Firebase 实时数据库中加载/检索多对多关系【英文标题】:How do I load/retrieve a Many to Many relationship in Firebase Realtime Database 【发布时间】:2019-02-20 01:49:00 【问题描述】:

在我的 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,我需要加载整个 Group 对象,以及该群组的其他用户(成员)。

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

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) 
        ...
    

);

我该如何正确、高效地做到这一点!?

【问题讨论】:

在这种情况下,更常见的是有四个***列表:groupsusersgroupUsersuserGroups。这允许您以一些额外的代码为代价精确加载您需要的内容。见***.com/questions/41527058/…。除此之外:您共享的代码有什么问题? 在我看来,我一定是做错了什么。为了让我的用户登录然后加入一个有 8 个用户的组,我将提出 10 或 11 个单独的请求。似乎有很大的失败空间 你在想什么类型的失败?这是相当多的代码,所以肯定有一些错误的空间。但这是一次性的事情,您应该在开发过程中轻松发现错误。之后,所有请求都通过一个连接进行,因此一个成功而另一个失败的可能性很小。 例如,一些“用户”调用失败,或者根本不返回(如果可能的话 - 你已经表示不返回)。另外因为它都是异步的,我必须等待并知道何时加载所有内容,然后再构造我的组对象 所有呼叫都通过同一个连接,因此多次呼叫因连接问题而失败的可能性并不比单次呼叫大。见***.com/questions/35931526/… 【参考方案1】:

在这种情况下,更常见的是有四个***列表:组、用户、groupUsers 和 userGroups。这允许您以一些额外的代码为代价精确加载您需要的内容。见Many to Many relationship in Firebase。

如果您担心问题,知道所有请求都通过一个连接可能会有所帮助,因此一个成功而另一个失败的可能性很小。由于连接问题导致一次失败的机会并不比单次呼叫更大。见Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly

【讨论】:

以上是关于如何在 Firebase 实时数据库中加载/检索多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Firebase 实时数据库中检索特定数据?

CollectionView 单元格未在视图控制器中加载

从firebase实时数据库IOS Swift中检索数据

如何从 Firebase 实时数据库中检索/获取项目

Firebase 实时数据库:如何在按值排序后围绕特定键检索 10 条记录?

如何使用颤振从firebase实时检索数据