Since Firestore is a NoSQL database and has no strict type rules and defined document structures, I think about handling corrupt data in my Flutter app.
In case you wonder why I want to request defensively, even when it is no third-party API -> I can think of three reasons why my app crashes because of corrupt data:
- I add wrong data via the Firebase console like using type
stringfor a field that should have been typenumber(happened repeatedly). - A bug in my app adds corrupt data to Firestore.
- A user has an old version of my app installed which can not handle the new Firestore data structure.
My requirements: The app should not crash when corrupt data from Firestore is requested, but the corrupt data should be reported so that the data can be fixed in Firestore a.s.a.p.
What do you think about the following approach?
Assume we have a model
Movie.The named constructor
fromparses the document data fromDocumentSnapshot.data()and returns our model. This works fine as long as the data has a fieldtitleof typeStringand a fieldrelease_yearof typeint(numberin Firestore).Let's assume the field
release_yearis missing in the actual data. This will let the request crash. Thus, the current user can't do anything with the respective movie and I as developer won't notice, because it happened silently on the device of the user.To fix the first issue, we can use defensive parsing with fallback data like this:
data['release_year'] ?? -1. No crash happens, but I as developer still don't notice and can't fix the data.To fix also this issue we could use Firebase Crashlytics. The only problem is that if we use defensive parsing to prevent crashing no log will be sent to Firebase. That's why I came up with this solution:
First, the app tries to parse the document data without any fallback mechanism. If the data is corrupt an exception is thrown and catched. In the catch block, the error is send to Firebase and then the defensive parsing constructor
fromCorruptis called to let the user continue in the app with the remaining data. InfromCorrupteach field is checked on null and type, before it is used to create the modelMovie. If a value is null or of a wrong type, a fallback value is used.What do you think of my approach? Am I overengineering?