# 결과물 미리보기
# 진행순서
- 리얼타임데이터베이스 dependencies에 추가하기
- 로그인시 리얼타임데이터베이스에 uid값 업데이트
- 로그인 후 새로운 액티비티에서 이름을 입력받고 리얼타임 데이터베이스에 업데이트
# dependencies 추가
implementation 'com.google.firebase:firebase-database-ktx'
# 로그인시 리얼타임 데이터베이스에 uid값 업데이트
맥락상 회원가입 성공시에 다뤄도 될 거 같다. 일단 파이어베이스의 auth를 통해 회원가입이 완료되면 그 계정에 대해서 고유 uid값을 얻게 되는데, 이 uid값을 이용해 DB를 다룬다.
handleSuccessLogin()함수를 만들어 추상화 한다.
private fun handleSuccessLogin() {
// TODO 파이어베이스에 로그인 정보를 리얼타임 데이터베이스에 저장해야함
// uid값 저장
if( auth.currentUser == null) {
Toast.makeText(this,"로그인 정보가 올바르지 않습니다",Toast.LENGTH_SHORT).show()
finish()
}
val userUid = auth.currentUser?.uid.orEmpty() // null일시 빈값으로 변경
val currentDB = Firebase.database.reference.child("Users").child(userUid)
val userInfoMap = mutableMapOf<String,Any>()
userInfoMap["userId"] = userUid
currentDB.updateChildren(userInfoMap)
val likeActivityIntent = Intent(this,LikeActivity::class.java)
startActivity(likeActivityIntent)
}
auth를 통해 받아온 currentUser 값은 nullable하다는 점에 주의하자.
orEmpty()는 받아온 값이 null일시 빈값으로 바꿔준다고 한다.
리얼타임 데이터베이스 구조는 child로 한단계씩 내려가서 정보를 저장할 수 있다.
위와 같다고 생각하면 된다. 위의 코드를 완료하면 userId까지의 값이 저장된다. 이렇게 DB에 값을 저장시키는 방법은 꽤 여러가지가 있다. 용도에 맞게 사용하자.
여튼 mutableMapOf을 이용하여 Map을 만들고 key-value쌍으로 보내주면 파이어베이스가 처리해준다.
# 로그인 후 새로운 액티비티에서 이름을 입력받고 리얼타임 데이터베이스에 업데이트
로그인을 완료하면 새로운 액티비티를 연결한다. 아직은 기능이 미구현이지만, 여기서는 간단히 다이얼로그를 만들어 값을 입력받고 그 값을 uid값을 이용해 새로 추가한다.
다이얼로그에 editText를 만들어서 값을 받아올때 상당히 애를 먹었는데, 매우매우 간단한 방법이 있었다. 꼭 기억해두자.
userDB = Firebase.database.reference.child("Users")
val currentUserDB = userDB.child(getUserID())
currentUserDB는 이제부터 로그인 된 유저의 데이터들이 들어있다.
리스너를 달아줘야한다. 여기서 변화를 감지하는 리스너가 꽤 많은데 구글링해보니까 사용에 주의해야한다고 한다. 계속해서 변화를 감지하게 하는 것도 있고, 한번만 감지하게 하는 것도 있다고 한다.
currentUserDB.addListenerForSingleValueEvent(object: ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
// 데이터가 변경되면 리스너가 감지함
// 최초(아무값도 없을때)로 실행 됐을때도 감지 됨
// TODO 다이얼로그를 만들고 데이터베이스에 동기화 시켜야함
if(snapshot.child("name").value == null ) {
showEditTextDiaglog()
return
}
// TODO 갱신할때 동작 정의
}
override fun onCancelled(error: DatabaseError) {
}
})
이렇게 현재 currentUserDB에서 변경사항을 감지한다. 현재 유저의 정보의 어떤 변화를 기다린다. snapshot이 DB의 조각이라고 생각하면 된다. object : ValueEventListener { ... } 와같이 익명객체의 인터페이스를 상속받아 사용하는 형태는 자주 사용 했지만 오랜만에 코틀린을 쓰다보니, 헷갈렸다. 인터페이스 상속이라는점에 유의하고 인터페이스를 상속받을 시 그 내부의 구현된 빈 함수들을 재정의 해줘야하는 것을 잊지말자.
## 간단하게 EditText 다이얼로그 만들기
이제 입력창 팝업을 만들어야한다. 매우매우 간단하게 만들 수 있었다.. 난 이거 만들려고 커스텀다이얼로그 만들고 인터페이스로 값 받아오고 쌩고생 했던 기억이 있다.
private fun showEditTextDiaglog() {
val editText = EditText(this)
AlertDialog.Builder(this)
.setTitle("이름을 입력해주세요")
.setView(editText)
.setPositiveButton("저장") { _ , _ ->
if(editText.text.isEmpty()) {
showEditTextDiaglog()
} else {
saveUserName(editText.text.toString())
}
}
.setCancelable(false)
.show()
}
바로 setView를 사용하면 되는데, 이렇게 View를 다이얼로그에 추가해줄 수 있다. 마치 setMessage를 사용하는거랑 똑같다.
private fun saveUserName(name: String) {
val userId = getUserID()
val currentUserDB = userDB.child(userId)
val user = mutableMapOf<String,Any>()
user["name"] = name
user["userId"] = userId
currentUserDB.updateChildren(user)
}
저장하는건 똑같이 하면 된다.
# 에러
## lateinit property auth has not been initialized
private lateinit var auth : FirebaseAuth
이렇게만 해놓고 auth.currentuser 와 같이 사용하는데 계속 오류가 났다. 당연했다..
// 해결
private val auth : FirebaseAuth = Firebase.auth
auth는 이렇게 만들어야 했다..
## Ignoring header X-Firebase-Locale because its value was null.
파이어베이스 회원가입시 자꾸 저 오류가 떴다. 난 다한거 같았는데, 찾아보니까 파이어베이스에서 회원가입할때 비밀번호가 너무 짧으면 생기는 오류였다. 최소 6자리 이상을 사용해야 한다고한다.