【问题标题】:Multiple Model Classes for same firebase element同一firebase元素的多个模型类
【发布时间】:2016-10-19 13:39:47
【问题描述】:

我正在使用一个使用 Firebase 作为数据存储库的应用程序。我只是重构整个应用程序以实现 Clean Architecture 和 RxJava。以这种方式做所有事情时,我发现管理我的模型对象时出现问题。

这是我的问题:我有一个 Post.class 具有相同的字段和值,我可以从 Firebase 数据库参考中检索到:

 public Post(Author author, String full_url, String full_storage_uri, String thumb_url, String thumb_storage_uri, String text, Object timestamp) {
    this.author = author;
    this.full_url = full_url;
    this.text = text;
    this.timestamp = timestamp;
    this.thumb_storage_uri = thumb_storage_uri;
    this.thumb_url = thumb_url;
    this.full_storage_uri = full_storage_uri;
}

目前一切正常。当我从存储库类中的 Observer 检索数据时,出现了我的问题:

@Override
public Observable<List<Post>> getPosts(final String groupId){
    return Observable.fromAsync(new Action1<AsyncEmitter<List<Post>>>() {
        @Override
        public void call(final AsyncEmitter<List<Post>> listAsyncEmitter) {
            final ValueEventListener PostListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                    final List<Post> postList = new ArrayList<>();
                    Log.e("Count ", "" + snapshot.getChildrenCount());
                    //For every child, create a Post object
                    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                        Post post = postSnapshot.getValue(Post.class);
                        Log.e("new post added ", postSnapshot.getKey());
                        //Set the databaseReference to the object, which is needed later
                        post.setRef(postSnapshot.getKey());
                        postList.add(post);
                    }
                    listAsyncEmitter.onNext(postList);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.e("The read failed: ", databaseError.getMessage());
                }
            };
            //Remove listener when unsuscribe
            listAsyncEmitter.setCancellation(new AsyncEmitter.Cancellable() {
                @Override
                public void cancel() throws Exception {
                    getPostsRef().child(groupId).removeEventListener(PostListener);
                }
            });
            //Set the listener 
            getPostsRef().child(groupId).addValueEventListener(PostListener);
        }
    }, AsyncEmitter.BackpressureMode.BUFFER);
}

有了这个观察者,我已经管理了所有的监听器和数据调用,我唯一的问题是这些行:

  //Set the databaseReference to the object, which is needed later
  post.setRef(postSnapshot.getKey());

我认为将引用设置为帖子模型中的新字段不是一个好习惯,它应该等于我的 firebase Json 树。所以我的问题是:创建 2 个不同的模型是一个好习惯吗?一个像“dbPost”和“PostEntity”。一个带有 firebase 值,另一个带有来自 dbPost 的构建器以及我要保存的新字段(dbReference 和 valueListener)?

【问题讨论】:

  • 您不只是将keyString 设置为新字段吗? postSnapshot.getRef()Reference。我错过了什么吗?
  • 是的,但我需要使用我在完全不同的类中调用我的 Obserser.Subscribe 的参考,并且我会收到一个帖子列表,并且在该列表中我需要保留每个帖子的 Ref他们
  • 但是为什么要用Observable 流包裹ValueEventListener?无论如何,您必须等待回调。
  • 当我取消订阅 observable(我在 Presenter 类的 onstop 方法中执行此操作)时,我将其包装以移除侦听器
  • 您可以使用 .removeEventListener(eventListener) 对 Ref 或 Firebase 查询执行相同操作。但我们跑题了。

标签: android firebase firebase-realtime-database rx-java


【解决方案1】:

最后我做的是创建两个不同的模型类。其中一个用于从 Firebase 检索和插入我的数据库参数,另一个用于我的应用程序使用它来管理具有应用程序所需的额外值的数据:

应用模型:

public class Post implements Parcelable{
private Author author;
private String full_url;
private String thumb_storage_uri;
private String thumb_url;
private String text;
private Object timestamp;
private String full_storage_uri;
private String ref;
private Achivement post_achivement;
private long post_puntuation;

public Post() {
    // empty default constructor, necessary for Firebase to be able to deserialize blog posts
}
[......]

Firebase 模型:

public class NetworkPost {
private Author author;
private String full_url;
private String thumb_storage_uri;
private String thumb_url;
private String text;
private Object timestamp;
private String full_storage_uri;
private Achivement post_achivement;
private long post_puntuation;

public NetworkPost() {
    // empty default constructor, necessary for Firebase to be able to deserialize blog posts
}

[...]

【讨论】:

    【解决方案2】:

    @Exclude 注解可用于排除某些字段更新到 firebase,因此您可以使用这些排除字段来存储自己的数据,如 post.ref

    我的应用程序中的示例:

    class LocationRecord {
        public final Integer id;
        public final String title;
        public final String address;
        public final Double latitude;
        public final Double longitude;
    
        @Exclude
        public Integer distance;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-15
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 2013-06-25
      • 1970-01-01
      相关资源
      最近更新 更多