简体   繁体   中英

How to use a Firebase auth listener in a repository class MVVM?

This is my MainActivity class:

class MainActivity : AppCompatActivity(), FirebaseAuth.AuthStateListener {
    @Inject lateinit var auth: FirebaseAuth

    override fun onAuthStateChanged(auth: FirebaseAuth) {
        val firebaseUser = auth.currentUser
        if (firebaseUser == null) {
            //Update UI
        }
    }

    override fun onStart() {
        super.onStart()
        auth.addAuthStateListener(this)
    }

    override fun onStop() {
        super.onStop()
        auth.removeAuthStateListener(this)
    }
}

Meaning that when the FirebaseUser becomes null for example (the user is signed out), I update the UI accordingly. It works fine but when it comes to MVVM, the activity knows about Firebase, which is not correct. I have this structure:

Activity -> ViewModel - Repository (calls to Firebase)

How to listen for auth changes in the repository class? Or is there any other solution?

In MVVM architecture we have an event-driven architecture everything that is happening in view model emits and observers get it in view(activity or fragment) in your case repository handles getting the user, then gives it to view model, then you should emit the result. take a look at this SingleLiveEvent in GitHub by google developers for architecture samples: https://github.com/android/architecture-samples/blob/dev-todo-mvvm-live/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/SingleLiveEvent.java here you use singleLiveEvent to Observe the changes just once, for things like your case with the state of the user just change after requesting for user state to fire base. create a SingleLiveEvent like this in your View model:

fun userState() : SingleLiveEvent<Boolean> = SingleLiveEvent()

then:

if(repo.getAuthUser() != null)
    userState().postValue(true)

and now you should observe it in your view like this:

viewModel.userState().observe(this, Observer {
    if (it!!)
        //user is created
    else
        //user is null
})

and for handling onStart and onStop in your viewModel, you can easily use Lifecycle-Aware Component:

in your view add observer on what will implement the "LifecycleObserver": I am going to put it on my viewModel like this:

lifecycle.addObserver(viewModel)

then make your viewModel the observer by extending it from "LifecycleObserver" and inside handle the lifecycles like this: class myViewModel: LifecycleObserver{

@OnLifecycleEvent(Event.ON_STOP)
    fun onStop() {
        //do some work1
    }

@OnLifecycleEvent(Event.ON_START)
    fun onStart() {
        //do some work2
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM