繁体   English   中英

如何使用 Flutter 防御性地从 Firestore 请求数据

[英]How to request data from Firestore defensively with Flutter

由于 Firestore 是一个 NoSQL 数据库,没有严格的类型规则和定义的文档结构,我考虑在我的 Flutter 应用程序中处理损坏的数据。

如果您想知道为什么我要防御性请求,即使它不是第三方 API -> 我可以想到我的应用程序因数据损坏而崩溃的三个原因:

  • 我通过 Firebase 控制台添加了错误的数据,例如对本应为number类型的字段使用类型string (重复发生)。
  • 我的应用程序中的错误会将损坏的数据添加到 Firestore。
  • 用户安装了我的应用程序的旧版本,无法处理新的 Firestore 数据结构。

我的要求:当请求来自 Firestore 的损坏数据时,应用程序不应崩溃,但应报告损坏数据,以便尽快在 Firestore 中修复数据

您如何看待以下方法?

假设我们有一部 model Movie

Movie {
  final String title;
  final int releaseYear;

  Movie({required this.title, required this.releaseYear});

  Movie.from(Map<String, dynamic> data)
      : title = data['title'],
        releaseYear = data['release_year'];
}

命名构造函数from解析来自DocumentSnapshot.data()的文档数据并返回我们的 model。只要数据具有String类型的字段titleint类型的字段release_year (Firestore 中的number ),这就可以正常工作。

假设实际数据中缺少字段release_year 这会让请求崩溃。 因此,当前用户不能对相应的电影做任何事情,作为开发者我也不会注意到,因为它是在用户的设备上悄悄发生的。

要解决第一个问题,我们可以像这样对后备数据使用防御性解析: data['release_year']?? -1 data['release_year']?? -1 没有发生崩溃,但我作为开发人员仍然没有注意到并且无法修复数据。

为了解决这个问题,我们可以使用 Firebase Crashlytics。 唯一的问题是,如果我们使用防御性解析来防止崩溃,则不会将任何日志发送到 Firebase。这就是我想出这个解决方案的原因:

final snapshot = await FirebaseFirestore.instance.collection('movies').doc('123').get();
try {
  return Movie.from(snapshot.data()!);
} catch (e) {
  await FirebaseCrashlytics.instance
      .recordError(e, e.stackTrace(), reason: 'data of movie ${snapshot.id} is corrupt');
  return Movie.fromCorrupt(snapshot.data()!);
}

首先,应用程序尝试在没有任何回退机制的情况下解析文档数据。 如果数据损坏,则会抛出并捕获异常。 在 catch 块中,错误被发送到 Firebase,然后调用防御性解析构造函数fromCorrupt让用户继续使用剩余数据在应用程序中。 fromCorrupt ,每个字段都在 null 和类型上进行检查,然后才用于创建 model Movie 如果值为 null 或类型错误,则使用回退值。

你觉得我的方法怎么样? 我是不是过度工程化了?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM