如何在存储库(MVVM)中分离Firestore SnapshotListener,

问题描述 投票:0回答:1

我相信我需要分离Firestore侦听器,但是如果不将上下文传递到我的存储库,我将看不到如何执行此操作。下面是一个示例:

片段

此方法在onViewCreated中被调用,只是更新了private var sitesList = ArrayList<SiteObject>(),它用于在我的recyclerview中设置列表:

    private fun setupObservers() {
        Log.d(TAG, "setupObservers()")
        businessViewModel.listenToSites().observe(viewLifecycleOwner, Observer { allSites ->
            if (sitesList != allSites && allSites != null) {
                sitesList.clear()
                sitesList.addAll(allSites)
                sitesAdapter.setList(sitesList)
                sitesAdapter.notifyDataSetChanged()
            }
        })
    }

ViewModel

    fun listenToSites(): LiveData<ArrayList<SiteObject>> {
        Log.d(TAG, "listenToSites()")
        return businessRepository.listenToSites()
    }

存储库

这是创建Firestore addSnapshotListener的位置:

  fun listenToSites(): LiveData<ArrayList<SiteObject>> {

        Log.d(TAG, "listenToSites(), firebaseUser = ${firebaseUser?.uid}")
        val userId = firebaseUser?.uid

        firestore.collection(SITES).whereEqualTo("users.${userId}", true)
            .addSnapshotListener(MetadataChanges.INCLUDE, EventListener { snapshots, e ->
                if (e != null) {
                    Log.w(TAG, "listenToSites(), listen error:", e)
                    return@EventListener
                }
                val allSites = ArrayList<SiteObject>()
                if (snapshots != null) {
                    for (document in snapshots) {
                        val site = document.toObject(SiteObject::class.java)
                        site.siteID = document.id
                        allSites.add(site)
                    }

                    for (docChange in snapshots.documentChanges) {
                        when (docChange) {
                            DocumentChange.Type.ADDED -> Log.d(TAG, "New site: ${docChange.document.data}")
                            DocumentChange.Type.MODIFIED -> Log.d(TAG, "Modified site: ${docChange.document.data}")
                            DocumentChange.Type.REMOVED -> Log.d(TAG, "Removed site: ${docChange.document.data}")
                        }
                    }

                    val source = if (snapshots.metadata.isFromCache){
                        "local cache"
                    }
                    else {
                        "server"
                    }
                    Log.d(TAG, "Sites data fetched from $source")
                }
                sitesMutableLiveData.value = allSites

            })

        return sitesMutableLiveData
    }

所以我想我可以通过将片段上下文作为这样的参数传递到链上来传递Fragment上下文:

businessViewModel.listenToSites(context)

将其通过VM,存储库传递给snapshotListener,如下所示:

addSnapshotListener(context, MetadataChanges.INCLUDE, EventListener....

但是不确定是否建议这样做或如何最好地捕获Fragment中的上下文?

快速红利问题出于兴趣; snapshots.documentChanges代码会创建其他侦听器吗?我只是在调试时使用,但认为可以。.

kotlin google-cloud-firestore listener android-livedata android-mvvm
1个回答
0
投票

您的存储库层不应包含任何一行与Android相关的代码。您的ViewModel是Android和repo层代码的共同点。您可以通过实现LifeCycleObserver接口使ViewModel生命周期感知。

class YourViewModel : LifeCycleObserver {

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP) //Annotate it with any lifecycle event of your choice.
  fun aMethodThatRemovesObserver() {
      //Invoked on onStop()
  }

}

在您的活动中:

onCreate() {
   lifecycle.addObserver(yourViewModel)
}

[无需担心手动删除ViewModel观察器,它会以ViewModel的onCleared状态消失。请记住,存储库层应保持与Android相关的代码。如果需要上下文,可以使用AndroidViewModel(作用于应用程序)。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.