同步Java OnComplete方法

时间:2019-03-23 23:57:43

标签: java android firebase google-cloud-firestore

我正在尝试访问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方法。

1 个答案:

答案 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 streamsfutures