Flutter realtime database onValue parsing
Just need to add a null check. like this;
.....
.onValue
.map((event) {
List<ListsModel> _offers = <ListsModel>[];
if(event.snapshot.value != null) {
final _resultList =
Map<String, dynamic>.from(e.snapshot.value as LinkedHashMap);
for (var key in _resultList.keys) {
Map<dynamic, dynamic> map = Map.from(_resultList[key]);
ListsModel listsModel = ListsModel.fromMap(map);
_offers.add(listModel);
}
}
.....
Michael m
Updated on December 28, 2022Comments
-
Michael m over 1 year
I'm experimenting with NoSQL (firebase realtime database) for the first time and I'm having some issues structuring and parsing data in a Flutter app. At first I had a simple "Person" model with some attributes and all was fine but then I had to introduce an ID as node and nesting the other attributes in order to perform CRUD operations and now I'm not able to parse my "updated" 'Person' model anymore. I don't know if that's ok but, for simplicity (I know it's not a proper ID), I decided that my ID ('personName' attribute) is the name of the person so the current structure on DB is:
I'm using freezed package and PersonDto looks like this (domains methods omitted):
@freezed class PersonDto with _$PersonDto { const PersonDto ._(); const factory PersonDto ({ required String personName, required int age, required String genre, required double height, required String hobby, required double weight, }) = _PersonDto ; factory PersonDto.fromJson(Map<String, dynamic> json) => _$PersonDto FromJson(json);
In the repository there's a method responsible to receive, parse and stream data from firebase. My problem is basically that I'm not able to generate a 'Person' model using the key of the node as an attribute for the 'name'. This is the closest I get :
Stream<Either<PersonFailure, List<Person>>> watchAll() async* { yield* _firebaseDatabase .reference() .child('persons') .onValue .map((event) { return right<PersonFailure, List<Person>>( (event.snapshot.value as LinkedHashMap).values.map((personMap) { final json = Map<String, dynamic>.from(personMap as LinkedHashMap); // //this snippet works. I'm able to generate a proper 'Person' model but like this //there's no way to retrieve the key from event.snapshot.value // json.addAll({ 'personName': 'NAME OF THE PERSON', }); return PersonDto.fromJson(json).toDomain(); }).toList()); }).onErrorReturnWith((e) { print('WATCH ERROR ${e.toString()}'); return left(const PersonFailure.unexpected()); }); }
Should be something like this, which likewise doesn't work, unfortunately:
yield* _firebaseDatabase .reference() .child('persons') .onValue .map((event) { (event.snapshot as LinkedHashMap).map((key, value) { final personName = key; final json = value as Map<String,dynamic>; json.addAll({'personName':personName}); // //error: The return type 'Person' isn't a 'MapEntry<_, _>', as required by the closure's context. // return PersonDto.fromJson(json).toDomain(); }); });