Синхронизированный метод Java OnComplete - PullRequest
0 голосов
/ 24 марта 2019

Я пытаюсь получить доступ к некоторым данным из коллекции 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;
}

Возвращенный результат - пустой список, потому что метод onComplete запускается после возврата getTransactions ().

1 Ответ

1 голос
/ 24 марта 2019

Как указано в комментариях, невозможно вернуть данные, которые еще не загружены, поэтому одним из способов сделать это является распространение обратного вызова.Вот простой пример:

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
  }
});

Конечно, вам может понадобиться распространять обратный вызов еще дальше, и это может легко перерасти в то, что называется адом обратного вызова.Вот почему некоторые люди предпочитают подход, который кажется синхронным, но на самом деле он асинхронный, то есть реактивные потоки или фьючерсы .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...