当前位置: 首页 > 知识库问答 >
问题:

在使用Cloud Firestore后端实现ViewModel类时需要帮助

饶骁
2023-03-14

我正在开发一个应用程序,它从云Firestore中获取一些文档,并在一个RecyclerView中显示文档的内容。我希望遵循关注分离的原则,并因此使用MVVM架构来构建应用程序。我已经使用FireStoreRecyclerAdapter为RecyclerView实现了一个数据类模型和适配器。

我已经在一个引导项目中工作过,该项目使用了MVVM体系结构和LiveData和Room。在该项目中,实现的适配器有一个ArrayList,它保存了所有的数据,这些数据又被用来填充RecyclerView。

viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(NoteViewModel::class.java)
viewModel.allNotes.observe(this, { list->list?.let{
            adapter.updateList(it)}
        })

类似地,我在一个使用Firestore但没有使用MVVM体系结构的项目中工作过。在后一种情况下,RecyclerView被数据膨胀,而没有将任何数据传递给任何集合。它甚至没有使用LiveData,但Firestore的变化立即反映了出来(我相信这是云Firestore的诸多好处之一)。

postDao = PostDao()
val postcollection = postDao.postCollections
val query = postcollection.orderBy("createdAt", Query.Direction.DESCENDING)
val recyclerviewOptions = FirestoreRecyclerOptions.Builder<Post>().setQuery(query, Post::class.java).build()


adapter = PostAdapter(recyclerviewOptions)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)

与上面的代码一样,只需将集合传递给适配器就可以膨胀RecyclerView。

但是现在在我要实现体系结构的这个项目中,我遇到了ViewModel类的问题。它应该包含什么?以及如何将FirestoreRecyclerOptions与ViewModel一起使用?我是否需要一个集合(如List或ArrayList)来将来自DAO的数据包装在LiveData中?还是我根本就需要LiveData?参考文档声明我应该在某个对象或集合上使用MutableLiveData,然后我应该有一个方法在每次数据更改时更新列表。还有一个observer方法被实现。但是我没有看到任何关于Firestore的解释,也没有看到FirestoreRecyclerAdapter是如何工作的。我需要的是我需要在ViewModel类中实现哪些内容,这些内容涉及来自数据库的集合上的MutableLiveData,以及云FirestoreRecyclerAdapter中的更新函数。

共有1个答案

宗意蕴
2023-03-14

类似地,我在一个使用Firestore但没有使用MVVM体系结构的项目中工作过。在后一种情况下,RecyclerView被数据膨胀,而没有将数据传递给任何集合。

这是因为您在Android中使用了Firebase-UI库,这意味着所有繁重的工作都是由这个库在幕后完成的。您所要做的就是只创建一个“FireStoreRecyclerOptions”对象,并将其传递给适配器,这就是它的全部内容。

它甚至没有使用LiveData,但Firestore的变化立即反映了出来(我相信这是云Firestore的诸多好处之一)。

不需要任何LiveData对象,因为实时获取数据的所有工作都是由库完成的。是的,Cloud Firestore是一个实时数据库,但您也可以在不使用库的情况下实现相同的行为。您可以使用Cloud Firestore客户端SDK,但所有这些机制都应该由您自己实现。因此,实时机制实际上是由Firebase-UI库提供的,而不是由云Firestore数据库本身提供的。要实时监听变化,请查看官方文档,使用Cloud FireStore获取实时更新:

您可以使用onSnapshot()方法监听文档。使用您提供的回调进行的初始调用将立即使用单个文档的当前内容创建文档快照。然后,每次内容更改时,另一次调用更新文档快照。

此外,

但是现在在我要实现体系结构的这个项目中,我遇到了ViewModel类的问题。

据我所知,您希望在项目中实现MVVM体系结构模式。在这种情况下,您必须为此编写代码,这意味着您应该通过分别创建一个模型、一个视图(activity或片段)和一个ViewModel来分离关注点。

以及如何将FirestoreRecyclerOptions与ViewModel一起使用?

您不能将Firebase-UI库与MVVM体系结构模式混合使用,因为它们都不兼容。是一个,还是另一个。

还是我根本就需要LiveData?

是的,您需要一个可以直接从activity/片段类在ViewModel类中观察到的LiveData对象。

参考文档声明我应该在某个对象或集合上使用MutableLiveData,然后我应该有一个方法在每次数据更改时更新列表。还有一个observer方法被实现。

是的,MVVM就是这样工作的。

但是我没有看到任何关于Firestore的解释,也没有看到FirestoreRecyclerAdapter是如何工作的。

您看不到“FireStoreRecyclerAdapter”的任何用法,因为您不能在MVVM体系结构模式中使用此类对象。之所以发生这种情况,是因为在创建“FireStoreRecyclerAdapter”类的新实例时,需要一个“FireStoreRecyclerOptions”对象,该对象应该传递给它的构造函数。这意味着这类物体紧挨着activity/碎片。所以如果你正在activity类中使用这类对象,你就打破了MVVM架构模式原则,该原则说activity应该对其数据源一无所知。

我需要的是我需要在ViewModel类中实现哪些内容,这些内容涉及来自数据库的集合上的MutableLiveData,以及云FirestoreRecyclerAdapter中的更新函数。

如上所述,对于MVVM体系结构模式,您不能这样做。非此即彼。您可以使用Firebase-UI库及其附带的所有优点,也可以使用MVVM体系结构模式。

你可能会想,哪个更好?

这取决于您认为什么更重要,库的好处还是体系结构模式的好处。如果你在问我,我更喜欢有一个简化的代码和使用库。

如果您想要一个更简单的代码,那么您可以使用Hilt的依赖注入,并将“FireStoreRecyclerOptions”类的实例直接注入到您的activity/片段类中。

请看下面我的一个存储库,作为使用MVVM从Firestore获取数据的示例:

  • https://github.com/alexmamo/swipetodelete/tree/master/app/src/main/java/ro/alexmamo/swipetodelete/products
 类似资料:
  • 问题内容: 我正在尝试通过覆盖ImplicitNamingStrategyJpaCompliantImpl类中的方法defineForeignKeyName来为外键列名添加下划线,但是不起作用。下面是我创建的类, 因此,除了defineForeignKeyName方法外,其他方法也可以按预期工作,例如为表添加复数名称和下划线。当我通过代码调试时,我可以看到该控件进入用于外键列的underlyFor

  • 我试图创建一个Java正则表达式,如果字符串末尾有奇数个反斜杠(),它将返回true,如果偶数,则返回false。 这是我的正则表达式 当我编译代码时,我得到以下异常 线程“main”java.util.regex.PatternSyntaxException中的异常:索引15^([^])(\)附近的未关闭字符类\$ 如果我使用M模式编译并运行良好,则可以使用反斜杠代替反斜杠 我知道这是一个逃避的

  • 我需要一些帮助用JSOUP解析这个html。我正在尝试从表中的每一列获取数据值。我一直在看JSoup文档,试图弄清楚我到底需要做什么,但还是不确定。看起来网站使用了CSS和内联格式的组合;其中大部分可以转换为CSS并减小页面大小。 这是html文件的一个小片段(实际上差不多有5 MB大小)。 更新:我已经更新了源代码,以更准确地显示html的结构。我假定tbody将位于表元素中是一个给定的条件。我

  • 如何使用Rethfit在同一个参数上添加多个图像/文件以及其他文本数据?

  • 我仍然是Java的新手,我正在努力使这个程序适合我的任务。 问题是: 杰夫在你家附近经营着一家当地的零售店。他已与您签订合同,让您创建一个交互式应用程序,以帮助他增加员工工资。创建一个名为 Details 的类,该类将包含员工 ID 号、名字、姓氏和薪水的获取和设置方法。包括一个名为getUpdateSalary()的方法,该方法将使员工的薪水增加10%。在您的主类中,包括一个名为 () 的静态方

  • 需要在 SQL 中将主键列更新为自动递增 我越来越不犯错, 关键字“身份”附近的语法不正确。