2 回答

TA貢獻1847條經驗 獲得超11個贊
這是一個異步調用(它啟動一個后臺進程來執行 Firebase 查詢,一旦完成它就會執行您的onComplete偵聽器),因此您不能指望在進行數據庫調用后立即獲得數據。例如,如果您的函數看起來像
void getData() {
final List<MyData> list = new ArrayList<>();
db.collection("cities")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
list.add(new MyData(document.getData()));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Log.d(TAG, "List size = " + list.size()); // will print 0
// list will be empty here, the firebase call will take hundreds
// to thousands of milliseconds to complete
}
您需要構建您的程序,以便它可以等待數據到達。有幾種方法可以做到這一點。一種是擁有list一個由onComplete偵聽器填充的類成員(然后您必須構建程序以處理隨機傳入的數據)。
另一種方法是擁有一個數據處理程序例程,它接受ArrayList并用它做一些事情。onComplete一旦您獲得所有數據,就可以從偵聽器調用此方法。例如:
void getData() {
db.collection("cities")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<MyData> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
list.add(new MyData(document.getData()));
}
processData(list);
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
}
void processData(List<MyData> data) {
// do stuff with the data, or make a copy, or otherwise share it
// with the rest of your program
}

TA貢獻1811條經驗 獲得超5個贊
我想讓我的程序將 document.getData() 調用的結果添加到可在內部類/方法之外訪問的 ArrayList。
在這種情況下,如果您使用的是模型類,則應該使用toObject()方法并YourModelClass以ArrayList如下方式添加類型的對象:
if (task.isSuccessful()) {
List<YourModelClass> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
YourModelClass yourModelClass = document.toObject(YourModelClass.class);
list.add(yourModelClass);
//Do what you need to do with your list
}
}
如您所見,我建議您使用YourModelClass回調中的對象列表。這是因為onComplete()方法具有異步行為,您不能簡單地在回調之外使用該列表,因為它始終為空。
嘗試更改 onComplete 方法的返回類型會產生錯誤。
更改方法的返回類型不會給您錯誤,但結果將始終是一個空列表。您現在無法返回尚未加載的內容。快速解決此問題的onComplete()方法是僅在方法內部使用該對象列表,正如我上面已經寫的,或者如果您想在外部使用它,我建議您從這篇文章中查看我的 anwser 的最后一部分,其中我已經解釋了如何使用自定義回調來完成。您也可以觀看此視頻以更好地理解。
添加回答
舉報