[英]How to constantly update query for Firebase Realtime Database with LiveData and ViewModel in Android
[英]Passing query parameters to LiveData/Viewmodel in Android app
由於我是 Android 應用程序編程新手,因此我遵循了有關如何使用 Android 架構組件和 Firebase 來實現 MVVM(使用 LiveData、ViewModel 等)的教程。
我遵循的教程可以在這里找到:
我現在剩下的是我認為 MVVM 的一個不錯的實現,但是我無法理解我應該如何將查詢參數傳遞給它。 現在我需要對要檢索的文檔的 ID 進行硬編碼:
public class AlarmDAO {
private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
public AlarmLiveData getFirestoreLiveData() {
DocumentReference documentReference = firebaseFirestore.collection(Collection.ALARMS.name).document("5RxJNuNyhDJlz49wpBkw");
return new AlarmLiveData(documentReference);
}
}
然后由擴展ViewModel
的類調用。
public class AlarmViewModel extends ViewModel {
private AlarmDAO DAO = new AlarmDAO();
private AlarmLiveData liveData = null;
public LiveData<Alarm> getAlarmLiveData() {
liveData = DAO.getFirestoreLiveData();
return liveData;
}
public LiveData<Alarm> getAlarm() {
return liveData.alarm;
}
}
然后我在我的活動中觀察這些數據:
model.getAlarmLiveData().observe(this, Observable -> {});
model.getAlarm().observe(this, alarm -> {
if (alarm != null) {
alarmTextView.setText(alarm.getTest());
else {
Log.d(TAG, "Waiting for data");
}
});
我的問題是我沒有看到查詢特定警報的方法。 例如model.getAlarm("someId")
。 我的印象是它應該在 DAO 和/或 ViewModel 中完成,但我不知道如何完成。 我不明白的另一件事是為什么我需要在我的活動中同時觀察model.getAlarmLiveData()
和model.getAlarm()
,因為只使用一個不起作用。 這兩個問題的答案很可能非常簡單,但到目前為止我還沒有弄清楚。
為了完整AlarmLiveData
:除了兩個字符串的 getter 和 setter 之外, Alarm
類什么也沒有,下面是AlarmLiveData
類。
public class AlarmLiveData extends LiveData<Alarm> implements EventListener<DocumentSnapshot> {
private static final String TAG = AlarmLiveData.class.getSimpleName();
private Alarm alarmTemp = new Alarm();
private DocumentReference documentReference;
private ListenerRegistration listenerRegistration = () -> {};
public MutableLiveData<Alarm> alarm = new MutableLiveData<>();
public AlarmLiveData(DocumentReference documentReference) {
this.documentReference = documentReference;
}
@Override
protected void onActive() {
listenerRegistration = documentReference.addSnapshotListener(this);
super.onActive();
}
@Override
protected void onInactive() {
listenerRegistration.remove();
super.onInactive();
}
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
if (documentSnapshot != null && documentSnapshot.exists()) {
alarmTemp = new Alarm();
alarmTemp.setId(documentSnapshot.getId());
alarmTemp.setTest(documentSnapshot.get("test").toString());
alarm.setValue(alarmTemp);
} else {
Log.d(TAG, "ERROR");
}
}
}
感謝閱讀,期待答案!
您必須同時使用model.getAlarmLiveData()
和model.getAlarm()
似乎是您的 AlarmLiveData 類擴展了 LiveData 但為包含的 MutableLiveData 成員變量設置了一個值,而不是設置其自己的類值。
在您的 AlarmLiveData 類中:
// Comment out/Remove your 'public MutableLiveData<alarm> alarm' member variable from the top.
// You're going to want to set the value of the AlarmLiveData class itself instead.
// ...
// Then inside of your onEvent callback
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
if (documentSnapshot != null && documentSnapshot.exists()) {
alarmTemp = new Alarm();
alarmTemp.setId(documentSnapshot.getId());
alarmTemp.setTest(documentSnapshot.get("test").toString());
// Set the value for the AlarmLiveData class directly
setValue(alarmTemp);
} else {
Log.d(TAG, "ERROR");
}
}
我不確定您為什么要創建 DAO 類,我很可能會將該代碼直接移到 AlarmViewModel 類中。 但是,如果您不想刪除它,您可以通過以下方式更改當前的 DAO 類:
// Pass in the document id you want to create a document reference for
public AlarmLiveData getFirestoreLiveData(String documentId) {
DocumentReference documentReference = firebaseFirestore.collection(Collection.ALARMS.name).document(documentId);
return new AlarmLiveData(documentReference);
}
您的 AlarmViewModel 類將如下所示:
public class AlarmViewModel extends ViewModel {
private AlarmDAO DAO = new AlarmDAO();
private AlarmLiveData liveData = null;
// Make sure to take in the document id so you can create the corresponding LiveData
public LiveData<Alarm> getAlarmLiveData(String documentId) {
// Only create a new LiveData instance if the current one is null.
// This is helpful if you intend to use this as a Shared ViewModel.
if(liveData == null){
liveData = DAO.getFirestoreLiveData(documentId);
}
return liveData;
}
}
最后,在您的活動中:
// Pass in the document id and observe the ViewModel
model.getAlarmLiveData("MY_DOCUMENT_ID").observe(this, alarm -> {
if (alarm != null) {
alarmTextView.setText(alarm.getTest());
}else{
Log.d(TAG, "Waiting for data");
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.