提问人:Vega180 提问时间:9/30/2021 最后编辑:Vega180 更新时间:9/30/2021 访问量:94
如何使用 Flutter 防御性地从 Firestore 请求数据
How to request data from Firestore defensively with Flutter
问:
由于 Firestore 是一个 NoSQL 数据库,没有严格的类型规则和定义的文档结构,因此我考虑在我的 Flutter 应用程序中处理损坏的数据。
如果你想知道为什么我想防御性地请求,即使它不是第三方 API - >我可以想到我的应用程序因数据损坏而崩溃的三个原因:
- 我通过 Firebase 控制台添加了错误的数据,例如将 type 用于本应键入的字段(反复发生)。
string
number
- 我的应用中的一个错误将损坏的数据添加到 Firestore。
- 用户安装了旧版本的应用,该版本无法处理新的 Firestore 数据结构。
我的要求:当请求来自 Firestore 的损坏数据时,应用程序不应崩溃,但应报告损坏的数据,以便可以在 Firestore a.s.a.p 中修复数据。
答:
您如何看待以下方法?
假设我们有一个模型。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'];
}
命名构造函数从中解析文档数据并返回我们的模型。只要数据具有 type 字段和 type 字段(在 Firestore 中),这就可以正常工作。from
DocumentSnapshot.data()
title
String
release_year
int
number
假设实际数据中缺少该字段。这将使请求崩溃。因此,当前用户无法对相应的电影执行任何操作,而我作为开发人员也不会注意到,因为它在用户的设备上默默地发生。release_year
为了解决第一个问题,我们可以对回退数据使用防御性解析,如下所示: .没有崩溃发生,但我作为开发人员仍然没有注意到并且无法修复数据。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,然后调用防御性解析构造函数,让用户继续在应用中处理剩余数据。在每个字段中检查 null 和 type,然后再使用它来创建模型。如果值为 null 或类型错误,则使用回退值。fromCorrupt
fromCorrupt
Movie
您如何看待我的方法?我是不是过度设计了?😅
评论