【问题标题】:How can I avoid code duplication when getting data from Firebase (android)?从 Firebase (android) 获取数据时如何避免代码重复?
【发布时间】:2018-07-09 21:24:48
【问题描述】:

我想这个问题将适用于任何使用异步调用的应用程序。

我对这一切都比较陌生,我遇到的问题是从 Firebase 获取数据到我的 Android 应用程序。

整个应用程序中有几个类需要使用数据库中“users”表中的数据,我获取如下:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference()
.child("users").child("exampleDataFromUsers");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // do something with the snapshot
    }

我想创建一个通用类来处理从 Firebase 检索数据,例如:

public class FirebaseDataHandler() {

  static String getUserReports() {
    // get Reports
  }

  static int getUserAge() {
    // get age
  }
}

但由于它是异步检索的,因此对这些方法的任何调用都只会返回 null。结果,我的代码目前充斥着重复的代码。

如果有人对实现此目标的更好方法有任何见解,将不胜感激。谢谢。

【问题讨论】:

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


    【解决方案1】:

    我相信这个问题会产生许多主要基于意见的好答案。但我还是会发表我的意见:

    我个人将 Firebase 与 Android Architecture Components 一起使用,它(来自文档)是:

    帮助您设计稳健、可测试和 可维护的应用程序。从管理 UI 组件的类开始 生命周期和处理数据持久性。

    该库提供 2 个类来让您了解数据生命周期:Live DataViewModel。您可以在 Firebase 博客上找到集成这两个库的指南: [Part1Part2Part3]

    要使用该库,您需要将 Google 存储库添加到项目的 build.gradle 文件中:

    allprojects {
        repositories {
            jcenter()
            google()
        }
    }
    

    然后添加对你应用的 build.gradle 文件的依赖:

    implementation "android.arch.lifecycle:extensions:1.1.0"
    

    所以你创建了一个从 LiveData 扩展的类:

    public class FirebaseQueryLiveData extends LiveData<DataSnapshot> {
        private static final String LOG_TAG = "FirebaseQueryLiveData";
    
        private final Query query;
        private final MyValueEventListener listener = new MyValueEventListener();
    
        public FirebaseQueryLiveData(Query query) {
            this.query = query;
        }
    
        public FirebaseQueryLiveData(DatabaseReference ref) {
            this.query = ref;
        }
    
        @Override
        protected void onActive() {
            Log.d(LOG_TAG, "onActive");
            query.addValueEventListener(listener);
        }
    
        @Override
        protected void onInactive() {
            Log.d(LOG_TAG, "onInactive");
            query.removeEventListener(listener);
        }
    
        private class MyValueEventListener implements ValueEventListener {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                setValue(dataSnapshot);
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.e(LOG_TAG, "Can't listen to query " + query, databaseError.toException());
            }
        }
    }
    

    然后创建一个 ViewModel 来加载这个用户的数据:

    public class UserViewModel extends ViewModel{
      private static final DatabaseReference USERS_REF =
          FirebaseDatabase.getInstance().getReference("users/exampleDataFromUsers");
    
      private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(USERS_REF);
    
      private final LiveData<String> liveData =
        Transformations.map(liveData, new Function<DataSnapshot, String> {
          @Override
          public String apply(DataSnapshot dataSnapshot) {
              //do something with the snapshot and return a String
          }
        });
    
      @NonNull
      public LiveData<String> getUserReports() {
          return liveData;
      }
    }
    

    最后,为了在你的活动中获取这些数据,你只需要调用你的 ViewModel 并观察它的 LiveData:

        UserViewModel viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
        viewModel.getUserReports().observe(this, new Observer<String>() {
                    @Override
                    public void onChanged(@Nullable String reports) {
                        if (reports != null) {
                            // update the UI here with values
                        }
                    }
                });
    

    【讨论】:

    • 很好的解释。投票赞成! ;)
    • 我一直在以完全不同的方式使用带有架构组件的 firebase,这真是令人大开眼界,非常感谢
    猜你喜欢
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    • 2021-03-06
    • 2014-03-07
    相关资源
    最近更新 更多