I am building my own flutter app with the help of the Flutter Firebase course from fireship.io. The courses repository is here.
However, since abandoning multiple streams - from my own tries before starting the course - in favor of classes with anonymous types, I receive the following error message and can't get my head around why.
Goal: I want a Stream with all documents from any firestore collection, in this case 'hochschulen'. The Collection exists and is filled with data. All fields are Strings.
Expected: No error message
Actual Result:
flutter: The following assertion was thrown:
flutter: An exception was throw by _MapStream<QuerySnapshot, List<University>> listened by
flutter: StreamProvider<List<University>>, but no `catchError` was provided.
flutter:
flutter: Exception:
flutter: NoSuchMethodError: Closure call with mismatched arguments: function 'Global.models.<anonymous
flutter: closure>'
flutter: Receiver: Closure: (dynamic, String) => University
flutter: Tried calling: Global.models.<anonymous closure>(data: _LinkedHashMap len:10)
flutter: Found: Global.models.<anonymous closure>(dynamic, String) => University
flutter:
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
I have tried:
- defining all expected types of all parameters
- I have looked at this and this and some more similar questions, but struggle to adapt to my code, because I can't find missing parameters.
- I do believe I understand that this issue probably occures because some type and/or parameter of something is mixed up or missing.
This is the widget where I want to load some data:
class LegalScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<List<University>>.value(
value: Global.universityRef.streamData(),
child: LegalScreenContent(),
);
}
}
This is my global class:
class Global {
static final FirebaseAnalytics analytics = FirebaseAnalytics();
static final Map models = {
// Dish: (data, id) => Dish.fromMap(data, id),
// Event: (data, id) => Event.fromMap(data, id),
// News: (data, id) => News.fromMap(data, id),
// Subject: (data, id) => Subject.fromMap(data, id),
University: ({Map data}) => University.fromMap(data: data),
// UserModel: (data, id) => UserModel.fromMap(data, id),
};
static final UserData<UserModel> userModelRef =
UserData<UserModel>(collection: 'users');
static final Collection<University> universityRef =
Collection<University>(path: 'hochschulen');
}
Here is the model for University:
class University {
String city;
String domain;
String mail;
String name;
String shortName;
String street;
String phone;
String website;
String zip;
University(
{this.city,
this.domain,
this.mail,
this.name,
this.shortName,
this.street,
this.phone,
this.website,
this.zip});
University.fromMap({Map data}) {
city = data['city'] ?? '';
domain = data['domain'] ?? '';
mail = data['mail'] ?? '';
name = data['name'] ?? '';
shortName = data['short_name'] ?? '';
street = data['street'] ?? '';
phone = data['tel'] ?? '';
website = data['website'] ?? '';
zip = data['zip'] ?? '';
}
}
Here is my Collection class:
class Collection<T> {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final String path;
CollectionReference ref;
Collection({this.path}) {
ref = _db.collection(path);
}
Future<List<T>> getData() async {
var snapshots = await ref.get();
return snapshots.docs
.map((doc) => Global.models[T](doc.data, doc.id) as T)
.toList();
}
Stream<List<T>> streamData() {
return ref.snapshots().map((snapshot) => snapshot.docs
.map((doc) => Global.models[T](data: doc.data()) as T)
.toList());
}
}