处理具有关系(iOS)的Firebase模型的模式

处理具有关系(iOS)的Firebase模型的模式,ios,swift,firebase,nosql,Ios,Swift,Firebase,Nosql,我正在寻找现有iOS应用程序中的模式示例(首选Swift,但我想这并不重要),以了解在使用Firebase(或任何NoSQL DB)时如何处理模型。复杂的原因是1)Firebase侦听数据更改的方式,以及2)将db请求逻辑排除在模型之外 假设我有这样的东西: struct User { let name: String let checkin: Checkin } struct Checkin { let name: String let coordinates

我正在寻找现有iOS应用程序中的模式示例(首选Swift,但我想这并不重要),以了解在使用Firebase(或任何NoSQL DB)时如何处理模型。复杂的原因是1)Firebase侦听数据更改的方式,以及2)将db请求逻辑排除在模型之外

假设我有这样的东西:

struct User {
    let name: String
    let checkin: Checkin
}

struct Checkin {
    let name: String
    let coordinates: Double
}
现在,当我决定在视图控制器中使用数据时,我将执行类似于
Database.Database()…reference()…
的操作,并在模型上使用一个方法解析JSON并将其插入模型中。现在,当它到达一个关系属性(在本例中,当创建
User
的实例时,
checkin
)时会发生什么?如果我想要具有所有子关系的完整用户模型,我只需要从Firebase获得类似
{checkin:someRandomCheckinId}
的东西。我可以通过ID进行另一次调用以获取签入,但在解析从Firebase接收的数据时,我必须在我的模型中执行该逻辑,这似乎并不理想-似乎逻辑最好属于VC(或VC调用的单独数据管理器类)。有更好的办法吗


此外,鉴于Firebase的一个主要功能,我希望能够监听更改。我无法想象一群听众污染了我的模型是件好事 这个问题有两个部分。第一个是如何在NoSQL文档存储中构造数据。第二个问题是如何用现代OO语言构造应用程序。两者都远远超出了Firebase和Swift的范围

对于第一部分,我建议您首先将相关数据保存在一起,以便快速访问。当使用这些类型的数据库时,由于数据是重复的,通常会有空间损失。这是可以的,因为与时间相比,空间相对便宜。在您的示例中,如果您经常希望在获取“用户”时获取所有“签入”,则将该用户的“签入”存储在该用户中。如果您习惯于使用RDB,那么您需要记住,使用这种类型的存储,您可以存储数据层,并且一个属性可以有多个值。确保您阅读了Firebase文档中有关如何访问数据的内容,因为他们对如何存储数据提出了一些建议,以避免浪费时间和空间。其主要思想是使数据更平坦,而不是太多的层次,并且记住,得到一个父对象也会得到它的所有子对象。这通常涉及一些数据重复


对于问题的第二部分,你需要再深入一点。从阅读软件工程原理开始。坚实的原则是最重要的,但还有许多其他的原则你应该遵守。一个原则是,您应该将相关数据和行为放在一起。另一种说法是,每个模块(类)都应该有一个单独的职责(更改的原因)。大多数iOS开发人员遵循非常糟糕的开发实践,将所有应用程序逻辑加载到ViewController中,这违反了许多原则。模型类不仅用于存储状态,还应该包含与该状态相关的行为。ViewController不应访问数据库,也不应了解数据库的任何信息。这应该发生在应用程序模型中的某个地方。如果每个类型都以特定的方式访问数据,则将该逻辑与该类型一起存储。如果所有类型的大部分内容都相同,则将该部分抽象出来

这个问题有两个部分。第一个是如何在NoSQL文档存储中构造数据。第二个问题是如何用现代OO语言构造应用程序。两者都远远超出了Firebase和Swift的范围

对于第一部分,我建议您首先将相关数据保存在一起,以便快速访问。当使用这些类型的数据库时,由于数据是重复的,通常会有空间损失。这是可以的,因为与时间相比,空间相对便宜。在您的示例中,如果您经常希望在获取“用户”时获取所有“签入”,则将该用户的“签入”存储在该用户中。如果您习惯于使用RDB,那么您需要记住,使用这种类型的存储,您可以存储数据层,并且一个属性可以有多个值。确保您阅读了Firebase文档中有关如何访问数据的内容,因为他们对如何存储数据提出了一些建议,以避免浪费时间和空间。其主要思想是使数据更平坦,而不是太多的层次,并且记住,得到一个父对象也会得到它的所有子对象。这通常涉及一些数据重复


对于问题的第二部分,你需要再深入一点。从阅读软件工程原理开始。坚实的原则是最重要的,但还有许多其他的原则你应该遵守。一个原则是,您应该将相关数据和行为放在一起。另一种说法是,每个模块(类)都应该有一个单独的职责(更改的原因)。大多数iOS开发人员遵循非常糟糕的开发实践,将所有应用程序逻辑加载到ViewController中,这违反了许多原则。模型类不仅用于存储状态,还应该包含与该状态相关的行为。ViewController不应访问数据库,也不应了解数据库的任何信息。这应该发生在应用程序模型中的某个地方。如果每个类型都以特定的方式访问数据,则将该逻辑与该类型一起存储。如果所有类型的大部分内容都相同,则将该部分抽象出来

嗨,马特,谢谢你花时间回复。相信我,我已经阅读了Firebase的所有文档很多次(实际上没有那么多)。我同意您/Firebase关于扁平化数据结构的观点,但这正是许多问题共同存在的地方