[英]How to request data from Firestore defensively with Flutter
由于 Firestore 是一个 NoSQL 数据库,没有严格的类型规则和定义的文档结构,我考虑在我的 Flutter 应用程序中处理损坏的数据。
如果您想知道为什么我要防御性请求,即使它不是第三方 API -> 我可以想到我的应用程序因数据损坏而崩溃的三个原因:
number
类型的字段使用类型string
(重复发生)。我的要求:当请求来自 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
类型的字段title
和int
类型的字段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.