J'essaie de créer une application en utilisant Flutter et Firestore. Lors du chargement d'une collection à partir de Firestore à l'aide de StreamBuilder pour l'afficher dans un ListView, j'obtiens l'erreur suivante
The following assertion was thrown building StreamBuilder<QuerySnapshot>(dirty, state:
I/flutter (26287): _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#d5638):
I/flutter (26287): type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'
I/flutter (26287): where
I/flutter (26287): _InternalLinkedHashMap is from Dart:collection
I/flutter (26287): Map is from Dart:core
I/flutter (26287): String is from Dart:core
Voici comment je veux obtenir des données du DocumentSnapshot
class Creator {
const Creator({this.creatorId, this.name});
Creator.fromDoc(DocumentSnapshot doc) : this.fromMap(doc.data);
Creator.fromMap(Map<String, dynamic> map) :
assert(map.containsKey('creatorId'),
assert(map.containsKey('name'),
this ( creatorId: map['creatorId'], name: map['name'] );
/*
...
*/
}
Et comment je veux l'utiliser
return Scaffold(
appBar: AppBar(title: new Text('Creators')),
body: StreamBuilder<QuerySnapshot>(
stream: CreatorRepo.getCreators().map<List<Creator>>((creators) {
return creators.documents.map<Creator>((c) => Creator.fromSnapshot(c)).toList();
}),
builder: (BuildContext context, snapshot) {
if ( snapshot.hasData ) {
return ListView.builder(
itemCount: snapshot.data.length,
builder: (context, index) {
final creator = snapshot.data[index];
return ExpansionTile(
title: Text(creator.name),
children: [
Text(creator.creatorId),
],
);
},
);
}
return const CircularProgressIndicator();
},
),
);
Dépendances:
dependencies:
flutter:
sdk: flutter
cloud_firestore: ^0.6.3
firebase_messaging: ^0.2.4
Firestore n'autorise que les clés String
et les valeurs dynamic
étant, à l'exception de Timestamp
, les types de langage de base. Le cloud_firestore
le plugin conserve les données du document dans un _InternalLinkedHashMap<dynamic, dynamic>
. Je pensais que le Map
à l'intérieur de tout DocumentSnapshot
serait Map<String, dynamic>
. Comment puis-je contourner cela? Modification de toutes les fonctions pour prendre Map<dynamic, dynamic>
et supposons que la clé est un String
est une solution de contournement plutôt laide au problème.
Je pense que c'est parce que la carte renvoyée par Firebase n'est pas un Map<String, dynamic>
mais plutôt Map<dynamic, dynamic>
.
Voir https://github.com/flutter/flutter/issues/17417 pour un problème connexe.
Utilisez Map<String, dynamic>.from ( mapFromFirestore )
. Cela crée un nouveau Map<String, dynamic>
du contenu de mapFromFirestore
, générant une erreur s'il trouve une clé qui n'est pas String
.
Flutter fonctionnait désormais avec Map<String,String>
Moi aussi, j'ai eu ce problème et l'ai résolu avec -
Map<String, dynamic> var = {'item': 0, 'name': 'John'}
au lieu de Map non spécifié.
Map var = {'item': 0, 'name': 'John'}