联接扁平化数据是一种常见的用例,也在documentation中进行了描述。但是文档显示了一个简单的示例,该示例不是实时的,它对更改没有反应。我正在寻找更可靠的实现。我认为RxJava对此非常理想。

考虑以下Firebase结构:

{
  "messages": {
    "group_id_1": {
      "message_id_1": {
        "text": "Hello",
        "author": "uid_1"
      }
    }
  },
  "users": {
    "uid_1": {
      "name": "David"
    }
  },
  "rooms": {
    "room_id_1": {
      "name": "General",
      "members": {
        "uid_1": true
      }
    }
  }
}

我在这里看到两个用例:
  • 获取带有作者姓名的组中的消息列表
  • 我想我会得到Observable<Message>,当我订阅它时,依赖项(那些消息的用户)也将在某些缓存中被订阅。当显示消息时,我可以从缓存中获取作者的姓名。
  • 这也是实时的-如果作者姓名更改,则可观察对象将发出更改的消息。
  • 当我取消订阅可观察项时,依赖项也取消订阅。
  • 获取房间成员及其姓名的列表
  • 我想我会得到Observable<User>,当我订阅它时,它将首先订阅 session 室的成员,然后再订阅单个用户。
  • 是实时的-如果 session 室成员发生变化,我会得到通知。
  • 当我取消订阅可观察项时,也取消了依赖项的订阅。

  • 您知道可以执行此操作的库/解决方案吗?

    或者,如果我创建了一个,您会用吗?

    最佳答案

    我打算提出这个问题的一个变种,但似乎最好是在这个问题的基础上...我将描述至少部分是上述问题的答案,但也有一个缺点看到。

    使用上述数据模型,我们可能会像下面这样围绕firebase查询创建RxJava包装器,以获取特定房间的成员 key 列表以及特定成员的详细信息(请注意在onCompleted()中使用subscriber.getMemberInfo ...稍后会详细介绍!)。

    public Observable<String> getRoomMembers(String roomId) {
        return Observable.create(subscriber -> {
            databaseReference.child(roomId + "/members").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
                        String userId = childSnapshot.getKey()
                        subscriber.onNext(userId);
                    }
                    subscriber.onCompleted();
                }
    
                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });
        });
    }
    
    public Observable<Member> getMemberInfo(String memberId) {
        return Observable.create(subscriber -> {
            databaseReference.child(memberId).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    Member member = dataSnapshot.getValue(Member.class);
                    subscriber.onNext(member);
                    subscriber.onCompleted();
                }
    
                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });
        });
    }
    

    然后,我们可以执行以下操作来获取特定房间的Member列表(已在isActive中添加了Member属性,以显示我们还如何过滤得到的结果)。
        getRoomMembers(roomId)
                .flatMap(memberId -> getMemberInfo(memberId))
                .filter(Member::isActive)
                .toList()
                .subscribe(members -> {
    
                });
    

    因此,以上工作到了一定程度。问题是我必须在subscriber.onCompleted()中调用getMemberInfo才能使上述对flatMap的调用正常工作....这意味着对Member数据的任何后续更改都不会触发上述订阅中的更新。对RxJavaFirebase来说相对较新,因此可能缺少明显的内容。

    10-07 19:24
    查看更多