Alternative to downcast DocumentSnapshot's generic #6179
-
Hello ! Dart does not allow for downcasting a class's generic type. This makes things like this not possible: @freezed
class Post with _$Post {
const factory Post.textPost(/** ... */) = TextPost;
const factory Post.pollPost(/** ... */) = PollPost;
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
}
final postsRef = _instance.collection('posts').withConverter<Post>(
fromFirestore: (snapshot, _) => Post.fromJson(snapshot.data()!),
toFirestore: (post, _) => post.toJson(),
); return StreamBuilder(
stream: _postsStream,
builder: (context, snapshot) {
// ...
final docs = snapshot.data.docs;
return ListView(
children: docs.map(
(doc) {
final data = doc.data();
return data.when(
textPost: (_textData) {
return TextCard(
// Fails
doc: doc as QueryDocumentSnapshot<TextPost>
);
},
pollPost: (_pollData) {
return PollCard(
// Fails
doc: doc as QueryDocumentSnapshot<PollPost>
);
},
);
},
),
);
},
); The error thrown is: type '_WithConverterQueryDocumentSnapshot<Post>' is not a subtype of type 'QueryDocumentSnapshot<TextPost>' in type cast That's fine if we can't do the conversion but it'd be great if there was a a way to somehow change that data type in another way. Currently final TextDoc = doc..data = _textData; Another option would be to just recreate the class but QueryDocumentSnapshot and its parents have no public constructors. The only other option I can think of is to create a wrapper class around DocumentSnapshot which has data as a field that I can Any advice? cc @rrousselGit |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
My recommendation would be to instead do: PollCard(
onChange: (newPost) => doc.set(newPost),
post: doc.data(),
); |
Beta Was this translation helpful? Give feedback.
My recommendation would be to instead do: