firebase 延迟加载Flutter/dart中的Firestore异物

ars1skjm  于 2023-05-01  发布在  Flutter
关注(0)|答案(1)|浏览(176)

我关于这个主题的很多搜索似乎都涉及分页。也许我问错了问题。如果是这样,请帮助编辑问题,使其有意义。
我所说的延迟加载外来对象是指只加载字符串id或引用路径,并在需要时将其转换为dart对象的行为。我试图复制Ormlite的外来对象字段的实现。
对于集合之间的复杂关系来说,这似乎是一个不用动脑筋的问题,因为如果没有必要,我不想读取被引用的对象。然而,我似乎找不到任何方法来轻松地使用Firebase。
让我们以下面的简单数据模型为例:

class Parent {
  String id;
  Child child;
}

class Child {
  String id;
  String description = 'child of parent';
  ParentCousin parentCousin;
}

class ParentCousin {
  String id;
  ChildCousin child;
}

class ChildCousin {
  String id;
  String description = 'child of ParentCousin';
}

这只是一个简单的模型,用于演示延迟加载对象的必要性。您可以想象,如果关系变得更复杂一些,那么预先加载所有对象将是繁重的,也是不必要的。有没有一个最佳实践来构建一个数据模型,在调用引用对象时延迟获取它?到目前为止我所想的是:

1.将每个被引用的数据模型封装到Map〈String,Object〉objRef中

这样,父对象的提取操作将存储id作为初始null对象的键。只有在引用objRef ['id']时才会创建对象。

2.将每个被引用的数据模型封装在一个专门的Reference类中

与第一种方法类似,引用类将保存一个id和对象。这种方法的优点是,类可以有由父类定义的专门方法来获取其子类。参见示例:

class Reference<T> {
  String id;
  T _object; 
  T Function() fetch;

  // Todo Constructor

  T get object => fetch;
}

3.创建占位符子对象

在这种方法中,子对象可以具有以下状态:

  • Unfetched -ID已填充,但其他字段尚未填充(未加载)
  • Fetch-填充id,填充(加载)其他字段
  • Empty -id是一个空字符串(不需要加载,没有子级)

我已经可以感觉到,这将是一个管理模型状态的锅炉板,更不用说我将逻辑引入模型本身,这打破了抽象规则,如MVC或Bloc模式。
有什么现有的解决方案或关于最佳实践的建议?

icnyk63a

icnyk63a1#

2年过去了,并没有一个简单的解决方案,但我更熟悉Firestore和NoSql,足以为那些寻找这样的解决方案。

缓存引用对象

1.将引用的对象缓存在Map中易于访问的位置,例如应用程序的控制器类。
1.每次查找父对象时,通过按id查找缓存的子对象来连接父对象和子对象。如果对象存在良好,如果不存在,则获取并缓存该对象,以便将来的查找已经被缓冲。
1.该高速缓存应该是短暂的,以帮助实现联接的目的,因为不能保证缓存的对象是最新的。因此,我建议在应用程序的生命周期内定期清除此缓存。确保对象是最新的唯一方法是在每次引用子对象时查找子对象-请参阅下一个解决方案

编写getter获取子对象

1.模型将有一个getter方法来获取对象。
示例代码:

// parent field
String childId;

// parent getter
Future<Child> get child => repo.fetch(childId);

1.如果您遵循任何类型的应用程序架构,例如域驱动设计,您会注意到这打破了关注点分离的规则。数据的获取应该是应用程序或基础架构层的关注点。为确保不跨越此边界,请使用扩展件在所选层中扩展模型。
选择最适合您需求的选项。两者都有利弊。
第一个选项是伟大的,如果您的数据没有改变太多,所以缓存它是足以保持网络调用到最低限度。
第二个选项是,如果您在每次引用时始终关心子数据的有效性。
在大多数情况下,我更喜欢第一种选择。

相关问题