https://www.masterqna.com/android/99827/%EB%A1%9C%EA%B7%B8%EC%9D%B8%ED%99%94%EB%A9%B4%EA%B3%BC-navigation-popupto-%EA%B4%80%EB%A0%A8
이전질문입니다.
-----------
결론만 먼저 말씀드리면 구현을 하는데 성공은 했는데 지금 몇가지 이상한점이 있고 궁금한점이 있습니다.
조건부 탐색 | Android 개발자 | Android Developers
기본 개념은 위 링크를 참고했는데 여기에는 ViewModel의 LiveData인 user를 어떻게 처음에 firebase에서 가져와 작성해야하는지 안나와있어서.. 어떻게해야할지 고민하고 찾다가
Advanced Android in Kotlin 06.2: Android Conditional Navigation with Login (google.cn)
(코드는 8번파트로 이동하셔서 Git 을 참고)
개발자 codelab에 다행히 비슷한 것을 구현한 것이 있어서 코드는 이곳꺼를 보면서 이해하고 사용하려고 했습니다.
1.
이곳 코드는 되기는한데 ViewModel에서 AuthenticationState를 강제로 UNAUTHENTICATED로 설정해주지 않으면 앱을 실행했을때 로그인화면으로 이동하지 않았습니다..
그러니까 앱을 시작할때 로그인을 하지 않았는데도 user 검사에서 null이 아니다(값이있다)라는 뜻이겠죠.
실제로 FirebaseUserLiveData 클래스와 ViewModel 클래스에서 user를 디버깅해보니
제가 이전에 로그인 기능을 구현한다고 만들어뒀던 아이디와 토큰값이 있었습니다.
그래서 FireBase에가서 계정값을 다 지워줬는데도 여전히 존재하네요.. cleanbuild와 Rebuild까지해봤는데도 그러네요..
왜이런지 모르겠습니다.
아래는 제가 사용한 코드입니다. (FirebaseUserLiveData는 그대로 사용)
class LoginViewModel : ViewModel() {
sealed class AuthenticationState {
object AUTHENTICATED: AuthenticationState()
object UNAUTHENTICATED : AuthenticationState()
}
val authenticationState = FirebaseUserLiveData().map { user ->
if (user != null) {
AuthenticationState.AUTHENTICATED
} else {
AuthenticationState.UNAUTHENTICATED
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loginVM.authenticationState.observe(viewLifecycleOwner) { authenticationState ->
when (authenticationState) {
LoginViewModel.AuthenticationState.AUTHENTICATED ->
Toast.makeText(context, "로그인 되어있음",Toast.LENGTH_SHORT).show()
LoginViewModel.AuthenticationState.UNAUTHENTICATED -> {
findNavController().navigate(R.id.login_nav)
}
}
}
}
2.
codelab 코드에서는 FirebaseUserLiveData라는 코드를 따로 만들어서 사용하던데 이유가 있을까요?
AuthStateListener를 사용하던데 FireBase 홈페이지를 보니 이것을 연결하면 기본 토큰의 상태가 변경될때마다 호출된다는데 계정의 토큰(UID)를 말하는 것이면.. 토큰은 고유한 값으로 알고있는데 변경될 일이있나요?
onActive()와 onInactive()도 화면 회전같은경우에만 쓰이는것같구요..
3.
그리고 이건 제가 codelab 코드를 보기전에 시도한 코드인데 이것은 왜안될까요?
ViewModel
class LoginViewModel : ViewModel() {
val user = MutableLiveData<UserAccount>().map { user ->
if(user != null) {
AuthenticationState.AUTHENTICATED
}
else
AuthenticationState.UNAUTHENTICATED
}
sealed class AuthenticationState {
object AUTHENTICATED : AuthenticationState()
object UNAUTHENTICATED : AuthenticationState()
}
}
Fragment
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loginVM.user.observe(viewLifecycleOwner) { user ->
when(user) {
LoginViewModel.AuthenticationState.AUTHENTICATED ->
Toast.makeText(context, "로그인 되어있음", Toast.LENGTH_SHORT).show()
else ->
findNavController().navigate(R.id.login_nav)
}
}
}
이 코드에서는 아예 if else문을 건너뜁니다. user를 임의로 null로 설정해보아도 그대로 넘어갑니다.
이유가 뭔가요?
+++++++++++++++
private fun firebaseSignIn() {
var email: String = binding.etId.text.toString()
var pwd: String = binding.etPwd.text.toString()
// Firebase Auth 진행
mFirebaseAuth.signInWithEmailAndPassword(email, pwd)
.addOnCompleteListener { task ->
if(task.isSuccessful) { // 로그인 성공
findNavController().navigate(R.id.main_graph)
Toast.makeText(context,"로그인 성공", Toast.LENGTH_SHORT).show()
}
else // 실패
Toast.makeText(context, "로그인 실패", Toast.LENGTH_SHORT).show()
}
}