안녕하세요. 백엔드 쪽은 공부해본적이 없어서 파이어베이스를 이용해 어플리케이션을 만들어 보는 중입니다. Auth 부분까지 잘 작동하는 것을 확인한 뒤, 공식 Documentation을 따라 실시간데이터베이스를 연결하고 코드를 짜봤는데요, 오류는 전혀 발생하지 않지만 데이터베이스에 제가 의도했던 어떠한 작업도 진행되지 않았습니다. 실시간데이터베이스 뿐만 아니라 파이어스토어도 마찬가지였습니다. 제 코드가 잘못된건가 싶어 Documentation에 있는 코드를 그대로 넣어봤으나 이 또한 작동하지 않았고 커넥트 및 디펜던스도 여러번 확인했습니다. 도대체 무엇이 문제일까요...? 아래는 파이어스토어 documentation에 있는 코드를 그대로 가져와 작성했던 코드입니다. class MainActivity : AppCompatActivity() { //파이어베이스 파이어스토어 초기화 val db = Firebase.firestore val user = hashMapOf( "first" to "Ada", "last" to "Lovelace", "born" to 1815 ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) db.collection("users") .add(user) .addOnSuccessListener { documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}") } .addOnFailureListener { e -> Log.w(TAG, "Error adding document", e) } }
먼저 로그 콘솔에 에러가 출력된 것이 있는지 확인을 해보시기 바랍니다.
공식 문서대로 실행했는데 에러가 없다면 일일이 로그를 추가하여 확인해보셔야 할 것 같습니다.
class MainActivity : AppCompatActivity() {
val db = Firebase.firestore
val user = hash...
class LogInActivity : AppCompatActivity() { var userId = "" var pcType = "" var nickName = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_log_in) val db: DatabaseReference = Firebase.database.reference // 이미 로그인이 되어있는 경우 UserApiClient.instance.accessTokenInfo { tokenInfo, error -> if (error != null) { Log.e("Token", "토큰 정보 보기 실패") } else if (tokenInfo != null) { Log.d("Token", "토큰 정보 보기 성공") UserApiClient.instance.me { user, error -> if (error != null) { Log.e("TAG", "사용자 정보 요청 실패", error) } else if (user != null) { val id = user.id.toString() setId(id) db.child("users").child(id).child("type").get().addOnSuccessListener { val dbType = it.value.toString() Log.i("info t", dbType.toString()) setType(dbType) }.addOnFailureListener { Log.e("firebase", "Error getting data", it) } db.child("users").child(id).child("nickname").get().addOnSuccessListener { val nick = it.value.toString() Log.i("info nick", nick) nickName = nick }.addOnFailureListener { Log.e("firebase", "Error getting data", it) } /*************************/ private fun setId(id : String) { userId = id } private fun setType(t : String) { pcType = t } 데이터 저장에 필요 변수는 전역으로 설정해주었습니다. db.child("users").child(id.toString()).child("type").get().addOnSuccessListener { 이 부분의 중괄호 내에서 dbType 변수에 데이터가 잘 저장된 걸 확인했습니다. 또한 전역변수로 선언해놓은 pcType에도 저장이 되어있습니다. 하지만 위 코드의 중괄호를 나가게 되면 pcType 변수에 다시 null 값이 들어 가 있습니다. nickName 처럼 set 메소드를 안 쓰고 직접 저장을 해도 똑같이 중괄호를 나가면 다시 null 값으로 돌아갑니다. 이와 마찬가지로 UserApiClient.instance.me에서 저장되는 id값도 중괄호를 벗어나면 null 값으로 됩니다.. 며칠 전만 해도 문제 없이 잘 저장되었던 걸로 알고 있었는데 갑자기 변수에 값이 저장이 안되니 막막합니다.. 제가 코틀린을 잘못 이해하고 사용하고 있는 것인가요? 파이어베이스에서 가져온 데이터 값을 어떻게 해야 변수에 저장할 수 있는지 궁금합니다. 현재 가지고 있는 코틀린 책도 없어서 구글링으로만 코드 작성 중이라 모르는 게 많습니다 ㅠㅠ..
addOnSuccessListener는 비동기로 실행됩니다.
즉, 언제 실행이 완료될 지 알 수 없는 코드입니다.
만약 중괄호 밖의 코드를 실행되기 전에 다행히 비동기 코드가 실행되었다면 정상적으로 동작하겠지만,
중괄호 밖의 코드가 실행될 때 아직 비동기 코드가 실행되어있지 않으면 값을 가져오지 못해 오류가 발생할 수 있습니다.
다시 말해,...