我有一个Firebase数据库。 我想创建一个查询并将其放在DBUtils类的方法中,以便可以从Android项目中的不同活动中调用该查询。
例如,类似:
ArrayList<String> aStringArrayList = DBUtils.GetAllJobsOnADate(Date date);
.
.
.
// use aStringArrayList to populate a listview.
AND
public static ArrayList<String> GetJobsOnADate(Date date) {
final ArrayList<String> mReturnList = new ArrayList<String>();
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("jobs")
.whereEqualTo("job_date", date)
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {
mReturnList.add(queryDocumentSnapshot.get("job_title"));
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// failure code
}
});
return mReturnList;
}
在调试应用程序时,我可以看到get()确实返回了QuerySnapshotDocument列表(可以在onSuccessListner代码中看到断点),但是aStringArray始终为空。
尝试使用AsyncTask(onPostExecute)。也不起作用。
当然,如果代码在同一活动中的函数中,则可以正常工作。但这就是散布在许多活动中的大量冗余代码。
有什么主意吗?
答案 0 :(得分:0)
唯一的原因是因为您实际上正在返回一个空列表,该方法是同步的,并且对服务器的Firebase调用是异步的,因此在return mReturnList;
之前调用mReturnList.add(queryDocumentSnapshot.get("job_title"));
由于我已经很长时间没有编写Java了,所以我建议您使用Kotlin的一些方法来实现。我将尝试使其类似于Java语法。
因此,为此,您应该使用接口与该类进行通信。
您的界面应如下所示:
interface Callback {
fun onListLoaded(list : ArrayList<String>)
}
然后在您的班级中需要该列表的人应该实现该接口:
class MyActivity() : Activity(), Callback /*<- your interface*/ {
...
//You implement the method which is signed in your interface.
override fun onListLoaded(list : ArrayList<String>) {
//here you can use the list
list.forEach { ... }
}
}
然后,您应将实现Callback
接口的活动实例传递给与Firebase通信的类:
class FirebaseInteractor() {
private var listener: Callback? = null //instance of your interface
fun setListener(listener : Callback) {
this.listener = listener
}
fun getJobsOnADate(Date date) {
...
}
}
然后,当您加载数据时,在onSuccessListener
中以这种方式调用界面:
fun getJobsOnADate(Date date) {
val db = FirebaseFirestore.getInstance()
db.collection("jobs")
.whereEqualTo("job_date", date)
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
val list : ArrayList<String> = ArrayList()
for (queryDocumentSnapshot in queryDocumentSnapshots) {
list .add(queryDocumentSnapshot.get("job_title"))
}
//Here goes the magic:
listener.onListLoaded(list)
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// failure code
}
})
}
这是您设置活动的方式,该活动将Callback
接口实现为侦听器(在活动内部):
val firebaseInteractor = FirebaseInterractor()
firebaseInterractor.setListener(this)
firebaseInterractor.getJobsOnADate(date)
调用firebase的onSuccessListener
并解析所有数据时,您的活动中的onListLoaded
将被交互者发送的列表调用。
答案 1 :(得分:0)
这是上述答案的Java实现。
static GetJobsOnADate(Date date, MyCallbackInterface callback) {
final ArrayList<String> mReturnList = new ArrayList<String>();
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("jobs")
.whereEqualTo("job_date", date)
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {
mReturnList.add(queryDocumentSnapshot.get("job_title"));
}
callback.OnDataReceived(mReturnList);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// failure code
}
});
}
和回调接口:
interface MyCallbackInterface{
void onDataReceived(ArrayList<String> data);
}