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 的最后一部分,其中我已经解释了如何使用自定义回调来完成。您也可以观看此视频以更好地理解。
添加回答
举报
