我在我的Android应用程序的单独线程中使用Cloud Firestore,所以我不想使用侦听器OnSuccessListener
和OnFailureListener
在另一个线程中运行。我可以让我的线程等待结果(并在需要时捕获任何异常)吗?
目前用于查询的代码如下所示:
FirebaseFirestore.getInstance().collection("someCollection").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
// do something on the UI thread with the retrieved data
}
});
我想要什么:
FirebaseFirestore.getInstance().collection("someCollection").getAndWaitForResult();
//Block the thread and wait for result, no callbacks.
//getAndWaitForResult() is not a real function, just something to describe my intention.
我以前曾经使用过Parse Server,在那里它非常琐碎。
您可以同步加载数据,因为DocumentReference.get()
返回Task
。所以你可以等待那个任务。
如果我做这样的事情:
val task: Task<DocumentSnapshot> = docRef.get()
然后我可以等待它通过做
val snap: DocumentSnapshot = Tasks.await(task)
当在 get() 之后将其他操作与可能需要一点时间的延续一起排边时,这很有用:
val task: Task = docRef.get().continueWith(executor, continuation)
上面,我正在一个单独的执行器上运行延续,我可以等待这一切完成 Tasks.await(task)
.
见 https://developers.google.com/android/guides/tasks
注意:您不能在主线程上调用 Tasks.await()。任务 API 专门检查此条件,并将引发异常。
还有另一种使用事务同步运行的方法。看到这个问题。
你可以在主线程上做这样的事情......
YourObject yourObject = (YourObject)new RunInBackground().
execute("someCollection","someDocument").get()
后台线程是...
public class RunInBackground extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
Task<DocumentSnapshot> documentSnapshotTask = FirebaseFirestore.getInstance().
collection((String) objects[0]).document((String) objects[1]).get();
YourObject obj=null;
try {
DocumentSnapshot documentSnapshot = Tasks.await(documentSnapshotTask);
obj = new YourObject();
obj.setter(documentSnapshot.get("your field"));
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return obj;
}
}
如果您使用的是 Kotlin,请添加一个扩展函数:
private suspend fun <TResult> Task<TResult>.await(): TResult? {
return try {
Tasks.await(this)
} catch (e: Exception) {
null
}
}
现在你可以做
val snapshot = fireStore.collection(USER_ROOT_PATH).document(documentPath)?.get()?.await()