我正在尝试访问Firestore集合中的某些数据。然后,我试图返回该一系列交易。但是由于OnComplete方法,我无法执行此操作。
public ArrayList<Transaction> getTransactions(){
//initializing firebase auth object
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = firebaseAuth.getCurrentUser();
//Establishing database connection
db = FirebaseFirestore.getInstance();
DocumentReference docRef = db.collection("users").document(currentUser.getEmail());
//this is the array I am trying to return.
ArrayList<Transaction> trans = new ArrayList<>();
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
//update the array with the data received.
trans = (ArrayList<Transaction>) document.getData().get("transactions");
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
return trans;
}
返回的输出为空列表,因为在getTransactions()返回之后将触发onComplete方法。
答案 0 :(得分:1)
如评论中所述,尚不可能返回尚未加载的数据,因此您可以通过传播回调来实现。这是一个简单的示例:
interface OnTransactionListReceivedListener {
void onTransactionListReceived(List<Transaction> result);
}
public void getTransactions(OnTransactionListReceivedListener listener){
//initializing firebase auth object
firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = firebaseAuth.getCurrentUser();
//Establishing database connection
db = FirebaseFirestore.getInstance();
DocumentReference docRef = db.collection("users").document(currentUser.getEmail());
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
listener.onTransactionListReceived((ArrayList<Transaction>) document.getData().get("transactions"));
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});;
}
我们定义了一个接口,该接口具有一个方法,该方法在接收到列表后即被调用。这是我们的回调。一旦Firebase返回列表,呼叫者将收到此列表。您可以像下面这样调用该方法:
getTransactions(new OnTransactionListReceivedListener() {
public void onTransactionListReceived(List<Transaction> result) {
// Use the list here
}
});
当然,您可能需要进一步传播回调,这很容易退化为所谓的回调地狱。这就是为什么有些人喜欢看似同步但实际上是异步的方法,即reactive streams或futures。