마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

MVVM 패턴 연습 중 쥘문입니다.

0 추천

Firebase Database를 사용하여 MVVM 패턴을 연습하고 있습니다. 

Repository에서 아래와 같이 사용하고자 하는데, "Cannot return a value from a method with void result type" 이라는 오류가 뜹니다. 그렇다고 FIrebase에서 가져온 데이터를 onComplete밖으로 끄집어 내어 return을 하자니 저 onComplete가 실행되기 전에 자동으로 비동기처리가 되어버려 getName함수가 끝나버릴 것 같은데, 어떻게 해야할까요?

public MutableLiveData<String> getName(){
    DocumentReference docRef = db.collection("Members").document("number1");
    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());

                    return new MutableLiveData<String>(document.getData().get("Name")+"");

                } else {
                    Log.d(TAG, "No such document");
                }
            } else {
                Log.d(TAG, "get failed with ", task.getException());
            }
        }
    });
}
ndmeng12 (120 포인트) 님이 2023년 5월 28일 질문

1개의 답변

0 추천

현재는 메소드가 LiveData를 리턴하지 않고 있기 때문에, 메소드가 LiveData를 리턴하도록 만드시면 됩니다.

public class MemberResult {
    private final Member member;
    private final Exception e;

   public MemberResult(Member member, Exception e) {
          this.member = member;
          this.e = e;
   }

    public MemberResult(Member member) {
          this.member = member;
          this.e = null;
   }

   public MemberResult(Exception e) {
          this.member = null;
          this.e = e;
   }

   public Member getMember() {
      return this.member;
   }

   public Exception getException() {
     return this.e;
  }
}

public MutableLiveData<MemberResult> fetchMemberById(String memberId){
    // 멤버변수로 빼서 사용하는 게 더 나은지 확인해서, 더 나은 방법을 사용하시길....
    final MuabelLiveData<MemberResult> liveData = new MutableLiveData<>();

    DocumentReference docRef = db.collection("Members").document(emmberId);
    docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot document = task.getResult();
                if (document.exists()) {
                     Member member =  document.toObject(Member.class);
                    Log.d(TAG, "DocumentSnapshot data: " + document.getData());

                    liveData.postValue(new MemberResult(member));

                } else {
                    Log.d(TAG, "No such document");
                    liveData.postValue(new MemberResult(new NoSuchElementExceptioin());
                }
            } else {
                Log.d(TAG, "get failed with ", task.getException());
                 liveData.postValue(new MemberResult(task.getException());
            }
        }
    });

   return liveData;
}

 

한가지 염두에 두실 점은 LiveData를 사용하는 것은 MVVM과는 사실 무관한 부분입니다. 더군다나 LiveData는 안드로이드에서만 제공되는 클래스라서 연습하시는 코드는 LiveData 사용법을 익히는 것에 좀 더 가깝다고 볼 수 있습니다. 랭귀지나 플랫폼에 상관없이 범용적으로 사용할 수 있도록 Listener를 등록/해제 하는 방법으로 연습하신 다음, LiveData 사용법을 익히시면 더 좋을 것 같습니다.

spark (226,420 포인트) 님이 2023년 5월 28일 답변
spark님이 2023년 5월 28일 수정
...