java - 从 Firebase (android) 获取数据时如何避免代码重复?

标签 java android firebase asynchronous firebase-realtime-database

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

我对这一切还比较陌生,我遇到的问题是从 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。因此,我的代码目前充斥着重复的代码。

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

最佳答案

我相信这个问题会根据意见产生很多好的答案。但无论如何我还是会发表我的看法:

我个人使用 Firebase Android Architecture Components ,(来自文档)是:

A collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.

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

要使用该库,您需要将 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;
  }
}

最后,为了在您的 Activity 中获取这些数据,您只需调用 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
                    }
                }
            });

关于java - 从 Firebase (android) 获取数据时如何避免代码重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48530800/

相关文章:

java - 这些 Java 注释有什么作用?

javascript - iOs 和 Android : create a bookmark -shortcut- in homescreen by javascript

Android Facebook SDK 4.0 外部注销

Android 创建一个 float 在锁屏上的 Activity

firebase - 尝试在Flutter项目上添加Firebase时遇到错误

Swift - 使用 URL 下载的低分辨率 firebase 照片

java - java eclipse代码完成中的这些数字 `10k` , `6k` , `1k` , `210` 是什么意思?

java - 选择行的列后,网格移动到 GWTEXT 的 EditorGridPanel 的左侧

java - 小部件未更新?

firebase - Flutter:Firebase 如何更改查询和内容