使用FireBase/FireStore访问Java内部函数中的数据

使用FireBase/FireStore访问Java内部函数中的数据,java,android,firebase,google-cloud-firestore,Java,Android,Firebase,Google Cloud Firestore,我正在使用谷歌的FireStore后端编写一个android应用程序。从官方文档中获取firestore集合中所有文档的代码如下: db.collection("cities") .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySna

我正在使用谷歌的FireStore后端编写一个android应用程序。从官方文档中获取firestore集合中所有文档的代码如下:

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());
                }
            } else {
                Log.d(TAG, "Error getting documents: ", task.getException());
            }
        }
    });
db.collection(“城市”)
.get()
.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
对于(QueryDocumentSnapshot文档:task.getResult()){
Log.d(标记,document.getId()+“=>”+document.getData());
}
}否则{
Log.d(标记“获取文档时出错:”,task.getException());
}
}
});
如果上面的代码输出到
Log.d(…)
,我希望我的程序将
document.getData()
调用的结果添加到内部类/方法之外可访问的
ArrayList
。我不确定做这件事的最好方法是什么。尝试更改
onComplete
方法的返回类型会产生错误。在这样的方法中是否有访问元素的标准方法

声明一个变量并尝试在类中进行变异也是不可能的,除非该变量是final,这就违背了这一点

我想让我的程序将document.getData()调用的结果添加到内部类/方法外部可访问的ArrayList

在这种情况下,如果您使用的是模型类,则应使用
toObject()
方法,并在
ArrayList
中添加类型为
YourModelClass
的对象,如下所示:

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
    }
}
if(task.issusccessful()){
列表=新的ArrayList();
对于(QueryDocumentSnapshot文档:task.getResult()){
YourModelClass YourModelClass=document.toObject(YourModelClass.class);
添加(yourModelClass);
//用你的列表做你需要做的事情
}
}
如您所见,我建议您在回调中使用
YourModelClass
对象列表。这是因为
onComplete()
方法具有异步行为,您不能简单地在回调之外使用该列表,因为它总是空的

尝试更改onComplete方法的返回类型会产生错误

更改方法的返回类型不会给您带来错误,但结果将始终是一个空列表。您现在无法返回尚未加载的内容。这个问题的一个快速解决方法是只在
onComplete()
方法中使用该对象列表,正如我在上面所写的,或者如果您想在外部使用它,我建议您查看我的anwser的最后一部分,我在中解释了如何使用自定义回调。您还可以查看此,以便更好地理解

我想让我的程序将document.getData()调用的结果添加到内部类/方法外部可访问的ArrayList

在这种情况下,如果您使用的是模型类,则应使用
toObject()
方法,并在
ArrayList
中添加类型为
YourModelClass
的对象,如下所示:

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
    }
}
if(task.issusccessful()){
列表=新的ArrayList();
对于(QueryDocumentSnapshot文档:task.getResult()){
YourModelClass YourModelClass=document.toObject(YourModelClass.class);
添加(yourModelClass);
//用你的列表做你需要做的事情
}
}
如您所见,我建议您在回调中使用
YourModelClass
对象列表。这是因为
onComplete()
方法具有异步行为,您不能简单地在回调之外使用该列表,因为它总是空的

尝试更改onComplete方法的返回类型会产生错误


更改方法的返回类型不会给您带来错误,但结果将始终是一个空列表。您现在无法返回尚未加载的内容。这个问题的一个快速解决方法是只在
onComplete()
方法中使用该对象列表,正如我在上面所写的,或者如果您想在外部使用它,我建议您查看我的anwser的最后一部分,我在中解释了如何使用自定义回调。您还可以查看此以便更好地理解。

这是一个异步调用(它启动后台进程来执行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
}

这是一个异步调用(它启动一个后台进程来执行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
}
你也可以看一看,为了更好的理解。你也可以看一看,为了更好的理解。