使用LiveData的FirebaseAuth.AuthStateListener.以下实施是否有改进余地?

Joh*_*nny 6 firebase firebase-authentication android-livedata android-viewmodel

在实施架构组件方面是否有改进的余地,或者通常考虑:

1)注意:如果您选择使用AuthStateListener,请确保在启动FirebaseUI流之前取消注册,并在流返回后重新注册它.FirebaseUI在内部执行auth操作,这可能会在流程完成之前触发侦听器.

LiveData

public class FirebaseAuthLiveData extends LiveData<FirebaseUser> {
    private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();

    private FirebaseAuth.AuthStateListener authStateListener = 
            new FirebaseAuth.AuthStateListener() {
                @Override
                public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
                    setValue(firebaseUser);
                }
            };

    @Override
    protected void onActive() {
        super.onActive();
        firebaseAuth.addAuthStateListener(authStateListener);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        firebaseAuth.removeAuthStateListener(authStateListener);
    }
}
Run Code Online (Sandbox Code Playgroud)

视图模型

public class FirebaseAuthViewModel extends ViewModel {
    private final FirebaseAuthLiveData firebaseAuthLiveData = new 
            FirebaseAuthLiveData();

    public LiveData<FirebaseUser> getFirebaseAuthLiveData() {
        return firebaseAuthLiveData; }
    }
}
Run Code Online (Sandbox Code Playgroud)

ManiActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FirebaseAuthViewModel firebaseAuthViewModel = 
    ViewModelProviders.of(MainActivity.this).get(FirebaseAuthViewModel.class);

    firebaseUserLiveData = firebaseAuthViewModel.getFirebaseAuthLiveData();

    firebaseUserLiveData.observe(MainActivity.this, new Observer<FirebaseUser>() {
        @Override
        public void onChanged(@Nullable FirebaseUser firebaseUser) {
            if (firebaseUser == null) {
                final Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
                        .setAvailableProviders(Collections.singletonList(                            
                            new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build())
                        ).build();
                startActivityForResult(intent, SIGN_IN);
            } else {
                updateUI(firebaseUser);
            }

        }
    });
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*amo 1

你快到了。您遇到的唯一问题是在活动中使用“FirebaseUser”对象,这打破了 MVVM 架构模式,即活动应该对其数据源一无所知。

因此,最简单、最干净的解决方案可能是使用 LiveData 类:

class AuthLiveData(
    private val auth: FirebaseAuth
): LiveData<Boolean>(), FirebaseAuth.AuthStateListener {
    override fun onAuthStateChanged(auth: FirebaseAuth) {
        value = auth.currentUser == null
    }

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

    override fun onInactive() {
        super.onInactive()
        auth.removeAuthStateListener(this)
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个存储库类:

class MyRepository {
    private val auth = FirebaseAuth.getInstance()

    fun getFirebaseAuthState(): AuthLiveData {
        return AuthLiveData(auth)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在 ViewModel 类中,我们可以简单地:

class MyViewModel: ViewModel() {
    val repository = MyRepository()

    fun getAuthState(): LiveData<Boolean> {
        return repository.getFirebaseAuthState()
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,在 Activity 中我们可以观察到 auth 状态的变化,如下所示:

viewModel.getAuthState().observe(this, { isUserSignedOut ->
    if (isUserSignedOut) {
        //Update the UI
    }
})
Run Code Online (Sandbox Code Playgroud)

这意味着我们始终知道用户何时登录,而不知道哪个是后端。