파이어베이스에서 읽어오는 데이터 값이 저장이 되지 않습니다.
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는 비동기로 실행됩니다.
즉, 언제 실행이 완료될 지 알 수 없는 코드입니다.
만약 중괄호 밖의 코드를 실행되기 전에 다행히 비동기 코드가 실행되었다면 정상적으로 동작하겠지만,
중괄호 밖의 코드가 실행될 때 아직 비동기 코드가 실행되어있지 않으면 값을 가져오지 못해 오류가 발생할 수 있습니다.
다시 말해, 중괄호 밖의 코드는 비동기 코드가 완료된 후에 실행될 필요가 있습니다.
비동기 코드가 실행 완료되었는지 확인하고 이 후의 코드를 실행하도록 만드는 방법으로는
Coroutines를 사용하거나 Tasks를 사용하는 방법이 있습니다.
Coroutines를 사용하는 예,
Tasks의 await()를 사용하는 예,