[英]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.