我相信我需要分离 Firestore 侦听器,但我看不到如何在不将上下文传递到我的存储库的情况下执行此操作。 下面是一个例子:
片段
此方法在onViewCreated
中调用,只是更新用于在我的回收器视图中设置列表private var sitesList = ArrayList<SiteObject>()
:
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()
}
})
}
视图模型
fun listenToSites(): LiveData<ArrayList<SiteObject>> {
Log.d(TAG, "listenToSites()")
return businessRepository.listenToSites()
}
存储 库
这是创建 FirestoreaddSnapshotListener
的位置:
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)
通过虚拟机、存储库将其传递到快照侦听器,如下所示:
addSnapshotListener(context, MetadataChanges.INCLUDE, EventListener....
但是不确定这是否是推荐的方法,或者如何最好地捕获片段中的上下文?
出于兴趣的快速奖励问题;snapshots.documentChanges
代码是否创建了额外的侦听器? 我只是在调试时使用,但认为可以。.
您的存储库层不应包含一行与 Android 相关的代码。您的 ViewModel 是 Android 和存储库层代码的共同基础。您可以通过实现LifeCycleObserver
接口来识别视图模型生命周期。
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)
}
无需担心手动删除视图模型观察器,它将在视图模型的状态下消失uncleared
。请记住,存储库层应该没有与 Android 相关的代码。如果需要上下文,可以使用AndroidViewModel
(范围限定为应用程序(。有时不可能分离出上下文,在这种情况下,我只会为它提供一个应用程序上下文,而不是一个活动上下文。