如何在Android中使用LiveData和ViewModel不断更新Firebase实时数据库的查询



我在Android中使用Firebase实时数据库和LiveData与ViewModel,我想不断更新查询。

下面是ViewModel类:

public class ViewModel_MainActivity extends ViewModel {

/*
LiveData with Database query for the Firebase node "Ratings"
*/
private static long currentTimeMillisRating = System.currentTimeMillis();
private static double pastMinuteForDisplayingRatings = 1;
private static long pastTimeMillisRatings = System.currentTimeMillis() - (long) (pastMinuteForDisplayingRatings * 60 * 60 * 1000);

private static final Query QUERY_RATINGS =
FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference().child(DB_SQLite_Firebase_Entries.FIREBASE_NODE_RATINGS).orderByChild(DB_SQLite_Firebase_Entries.FIREBASE_RATINGDATEINMILLISECONDS).endAt(pastTimeMillisRatings);

private final LiveData_FirebaseRating liveData_firebaseRating = new LiveData_FirebaseRating(QUERY_RATINGS);
@NonNull
public LiveData_FirebaseRating getDataSnapshotLiveData_FirebaseRating() {
Log.e("LogTag_ViMo", "pastTimeMillisRatings: " + pastTimeMillisRatings);
return liveData_firebaseRating;
}

}
下面是LiveData类:
public class LiveData_FirebaseRating extends LiveData<DataSnapshot> {
private static final String LOG_TAG = "LiveData_FirebaseRating";
private Query query;
private final LiveData_FirebaseRating.MyValueEventListener listener = new LiveData_FirebaseRating.MyValueEventListener();
DataSnapshot currentDataSnapShotFromFirebase;
public LiveData_FirebaseRating(Query query) {
this.query = query;
}
public LiveData_FirebaseRating(DatabaseReference ref) {
this.query = ref;
}
public void changeQuery(Query newQuery) {
this.query = newQuery;
}
public DataSnapshot getCurrentDataSnapShotFromFirebase() {
return currentDataSnapShotFromFirebase;
}
public void setCurrentDataSnapShotFromFirebase(DataSnapshot currentDataSnapShotFromFirebase) {
this.currentDataSnapShotFromFirebase = currentDataSnapShotFromFirebase;
}
@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());
}
}
}

下面是主活动的一部分,在这里创建和观察实时数据和视图模型:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);

/*
Initiate View Model with LiveData for Firebase
*/

rootRef_Firebase = FirebaseDatabase.getInstance(DB_SQLite_Firebase_Entries.FIREBASE_URL).getReference();
viewModel = new ViewModelProvider(this).get(ViewModel_MainActivity.class);
liveData_firebaseRating = viewModel.getDataSnapshotLiveData_FirebaseRating();
liveData_firebaseRating.observe(this, new Observer<DataSnapshot>() {
@Override
public void onChanged(@Nullable DataSnapshot dataSnapshot) {
liveData_firebaseRating.setCurrentDataSnapShotFromFirebase(dataSnapshot);
if(liveData_firebaseRating.getCurrentDataSnapShotFromFirebase()!=null) {
//Do something with the dataSnapshot of the query
}
}// end onChange
}); //end observe

}

所以我的问题在于ViewModel_MainActivity类中的QUERY_RATINGS没有更新。我想要的是返回FIREBASE_NODE_RATINGS中其属性FIREBASE_RATINGDATEINMILLISECONDS大于1分钟的所有节点(这意味着条目是在当前时隙之前至少1分钟创建的)。我怎样才能得到这些节点呢?

FirebaseQuery对象是不可变的,它们的参数是固定值。因此,没有办法更新现有的查询,也没有"一分钟前"。自动更新的值。

我能快速想到的选项:

  • 频繁创建新的查询,以捕获新的完整范围的相关节点。
  • 频繁地创建一个新的查询,只捕获新的节点(通过组合startAtendAt)并将它们与您已经拥有的结果合并。
  • 从查询中删除条件,并在应用程序代码中执行过滤。

根据我所知道的,我可能会从第三个选项开始,因为它似乎是最简单的。

最新更新