【问题标题】:How do I handle too early observation of LiveData that depend on firebase auth state to be AUTHENTICATED?如何处理对依赖于 Firebase 身份验证状态的 LiveData 的过早观察以进行身份​​验证?
【发布时间】:2020-04-09 00:36:18
【问题描述】:

在我的 Fragment 的 onViewCreated 中,我有一个基于身份验证状态的重定向,并且还绑定了 Frag 的观察者,如下所示:

class TodoMvvmFragment : Fragment() {
  private val loginViewModel by viewModel<LoginViewModel>()
  private val todoViewModel by viewModel<TodoViewModel>()
  val TAG = "TODO_FRAG"
  var rvAdapter:TodoListAdapter? = null
  var observersBound = false

   ///...omitted

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    rvAdapter = TodoListAdapter(todoViewModel, this )
    todo_rv.let {
        it.adapter = rvAdapter
        it.layoutManager = LinearLayoutManager(requireActivity())
    }

    loginViewModel.authenticationState.observe(this, Observer {
        when(it) {
                LoginViewModel.AuthenticationState.UNAUTHENTICATED -> {
                    findNavController().navigate(R.id.action_global_loginFragment)
                }
                LoginViewModel.AuthenticationState.AUTHENTICATED -> {
                    // Viewmodel calls aspects of the repository that rely on AUTHSTATE
                    // to be AUTHENTICATED, so don't bind observers until we are.
                    if (!observersBound) {
                        observersBound = true
                        todoViewModel.init()
                        bindObservers()
                        addListeners()
                    }

                }
                else -> {
                    Log.d(TAG, it.toString())
                }

        }
    })




}

这是有问题的观察者:

  fun bindObservers() {
    todoViewModel.getFilteredTodos().observe(this, Observer{
        if (it.data == null) {
            handleException("Error with todos by timestamp query", it.exception)
        } else {
            val todos: List<Todo> = it.data.map { todoOrException ->
                if( todoOrException.data == null) {
                    handleException("error with individual Todo", todoOrException.exception)
                    null
                } else {
                    todoOrException.data
                }
            }.filterNotNull()

            rvAdapter?.submitList(todos)
        }
    })

这会渗透到 repo,它会创建一个 firebase 查询。请注意 .document(auth.uid.toString())... 如果在用户授权之前创建此查询,则不会返回任何数据。

fun allTodosQuery(): Query {
    return firestore.collection(PATH_ROOT)
        .document(PATH_APPDATA)
        .collection(PATH_USERS)
        .document(auth.uid.toString())
        .collection(PATH_TODOS)
        .orderBy(FIELD_TIMESTAMP, Query.Direction.DESCENDING)

回到身份验证状态侦听器,我仅在身份验证状态更改为已身份验证时绑定观察者。我也用一个布尔值来保护它,这样它只发生一次。当我不这样做时,只是在身份验证状态侦听器之后将观察者绑定到 onViewCreated 中,我没有获得有关应用程序初始加载的任何数据。

我的问题是如何保持依赖于 authstate 身份验证的 livedata 在用户通过身份验证之前绑定到任何内容时不会遗漏任何内容。本质上,如何避免在用户通过身份验证之前从存储库中获取带有 null auth.uid 的错误查询?

【问题讨论】:

    标签: android firebase mvvm viewmodel android-livedata


    【解决方案1】:

    感谢您允许我玩橡皮鸭。这是一个解决方案:

    var _queryResult = Transformations.switchMap(_authState){
        if (_authState.value == LoginViewModel.AuthenticationState.AUTHENTICATED) {
            repo.getAllTodosByTimestamp()
        } else {
            MutableLiveData<ListOrException<TodoOrException>>()
        }
    }
    

    这样,在经过身份验证之前,我们不会构造或触发查询(在 repo 中)。

    【讨论】:

      猜你喜欢
      • 2013-07-10
      • 1970-01-01
      • 2017-03-11
      • 2014-05-18
      • 1970-01-01
      • 2017-09-18
      • 2013-01-27
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多