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

파이어베이스의 값을 static 변수에 저장 후 참조하는데 NULL값이 저장되는 문제가 있습니다.

0 추천
안드로이드 스튜디오로 카풀 앱을 제작하고 있습니다. 카카오 로그인 API를 사용하여, 각 사용자는 카카오 ID로 구별됩니다. 사용자들이 입력한 목적지 정보가 파이어베이스 실시간 데이터베이스에 올라갑니다. 직접 제작한 findMatching() 함수를 통해 나와 동일한 목적지를 입력한 사용자가 발견되면, 나와 상대의 실시간 위치를 카카오 지도에 띄우려고 합니다. 다음은 findMatching() 함수의 앞부분 입니다.

 

private void findMatching() {
    String myKakaoID = LoginActivity.mykakaoID;
    DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Users");
    usersRef.child(myKakaoID).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String myDestination = dataSnapshot.child("destination").getValue(String.class);
            String myUserType = dataSnapshot.child("usertype").getValue(String.class);
            Query matchingquery = usersRef.orderByChild("destination").equalTo(myDestination);
            matchingquery.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    boolean foundMatch = false;
                    User myUser = dataSnapshot.child(myKakaoID).getValue(User.class);

                    for (DataSnapshot matchSnapshot : dataSnapshot.getChildren()) {
                        User matchUser = matchSnapshot.getValue(User.class);
                        String matchKakaoID = matchSnapshot.getKey();
                        my_ID = myKakaoID;
                        match_ID = matchKakaoID;
                        
                        String matchName = matchUser.getName();
                        
                        if (!matchKakaoID.equals(myKakaoID) && matchUser.getUsertype() != myUser.getUsertype() && !isMatching) {
                            foundMatch = true;
                            isMatching = true; // 중복 매칭 방지용 변수 값 변경
                            Toast.makeText(MatchingActivity.this, matchName+"님과 매칭되었습니다! ", Toast.LENGTH_LONG).show();
                            //매칭후 내 목적지정보, 유저타입 삭제
                            DatabaseReference currentUserRef = usersRef.child(myKakaoID);
                            currentUserRef.child("destination").setValue(null);
                            currentUserRef.child("usertype").setValue(null);
                            // 매칭된 사용자의 목적지 정보, 유저타입 삭제
                            /*DatabaseReference matchedUserRef = usersRef.child(matchKakaoID);
                            matchedUserRef.child("destination").setValue(null);
                            matchedUserRef.child("usertype").setValue(null);*/
                            Intent mapintent = new Intent(MatchingActivity.this, MainActivity.class);
                            mapintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                            mapintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(mapintent);
                            break;
                        }
                    }

 

그런데,
for 문 안에 my_ID, match_ID변수는 해당 클래스 안에 public static string으로 선언되어있습니다.

다른 클래스에서 다음과 같이 참조해서 변수에 저장하면 해당 부분에서 nullpointerexception이 발생합니다.
String my_kakaoID =MatchingActivity.my_ID;
String match_kakaoID =MatchingActivity.match_ID;

NULL값이 스태틱변수에 저장되는것인지 아니면 참조가 제대로 이루어지지 않는 것인지 아니면 파이어베이스 문제인지 궁금합니다.

추가 정보가 필요하시면 알려주세요. 답변 부탁드립니다. 감사합니다...
안드로이드스튜 (120 포인트) 님이 2023년 5월 11일 질문

1개의 답변

0 추천
궁금하신 부분은 브레이트 포인트를 걸어서 디버깅을 해보시기 바랍니다.
참고로 안드로이드에서는 MainActivity같은 곳에 public static으로 상태를 저장하는 건 권장하지 않습니다. 디버깅이 골치 아픈 문제의 원상이 돨 수 있습니다.
해당 변수들은 멤버 변수로 만드셔서 처리하시고 db나 preference 또는 파일 등에 저장하시는거나 아니면 Appilication 클래스의 private에 해당 정보를 가진 인스턴스를 만들고 이걸 Activity.getApplication를 typcasting해서 사용하는 것이 더 낫습니다. 제 경험상 public static이라 할지라도 시스템이 생명주기를 관리하므로 갑자기 초기화가 되는 경우가 발생할 수 있습니다.

그리고 Activity에서 멤버변수를 만들고  onStop에 bundle에 값을 저장했다가 onStart에 복구하는 옵션도 고려해 보세요. Activity에서만 해당 값을 참조한다면 이게 제일 좋은 옵션입니다.
spark (227,970 포인트) 님이 2023년 5월 11일 답변
답변 정말 고맙습니다. 계속 수정 해 볼게요.
그런데, 올리신 코드에서 MatchingActivity.my_ID에 값을 할당하는 부분이 없는 것 같은데요. 이렇게 되면 당연히 해당 변수를 읽어올 수가 없는데, 어디서 값이 할당되는지 잘 체크해 보세요.
혹시, 아래코드가 값이 할당되는 부분인가요?
my_ID = myKakaoID;
match_ID = matchKakaoID;

이게 맞다면 위의 코드에서 파이어베이스 처리가 성공적으로 되어서 해당 코드가 제대로 호출되는지 확인해 보시길 바랍니다.

그리고 for 문 내에서 my_ID와 match_ID에 값을 할당하는 부분도 좀 이상해 보입니다. 매칭이 되었을 때만 my_ID와 match_ID에 값을 할당해야만, 매칭이 된 유저가 없을 때는 엉뚱한 값이 할당이 될 것 같아 보이는데요.
...