颤动和提供者,"type 'List<dynamic>' is not a subtype of type 'User'"
Flutter & Provider, "type 'List<dynamic>' is not a subtype of type 'User'"
Flutter 在运行时抛出异常:"type 'List' is not a subtype of type 'User'" 使用 StreamProvider 从 Firestore 检索数据时。
可以使用 .cast() 或 List.from() 对 'User' 中的数据强制执行类型安全,但这对断言没有影响。即使在 'User' 中将有问题的列表定义为动态也不会更改错误。
我已经广泛阅读了这方面的内容,例如 Github issue, typesafe Dart, and 。 None 这些解决方案有帮助,所以希望这里有人可以帮助我。
最小代码示例
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: StreamProvider<User>.value(
value: userData,
builder: (context, snapshot) {
return MyHomePage(title: 'Demo Error');
}
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final User userData = Provider.of<User>(context) ?? []; // This asserts at runtime
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$userData.name',
),
],
),
),
);
}
}
User _getUserFromSnapshot(DocumentSnapshot snapshot){
List<String> categoriesFromDb = (snapshot.data['categories'] as List).cast<String>(); // Cast does not work
return User(uid: '8GX2aGVn0GTrwLMxSZgx6STdnnA3',
name: snapshot.data['name'],
email: snapshot.data['email'],
phone: snapshot.data['phoneNumber'],
categories: categoriesFromDb,
surname: snapshot.data['surname'],
);
}
Stream<User> get userData{
return Firestore.instance.collection('users')
.document('8GX2aGVn0GTrwLMxSZgx6STdnnA3')
.snapshots().map<User>(_getUserFromSnapshot);
}
class User {
final String uid;
final String name;
final String surname;
final String phone;
final String email;
final List<String> categories;
User({this.uid, this.name, this.surname, this.email, this.phone, this.categories})
: super();
}
重现步骤:
-> 使用 StreamProvider 从 Firestore 集合中检索字符串数组。
-> 将 Firestore 数据映射到自定义类型('User' 在我的例子中)。
-> Flutter 在运行时断言。
发生这种情况是因为初始统计没有数据,所以它是 returns 列表,但您正试图将其分配给用户类型,因为您正面临此错误。
您可以通过检查运行时类型来解决,如下所示。
final User userData = Provider.of<User>(context).runtimeType == User
? Provider.of<User>(context)
: null;
Flutter 在运行时抛出异常:"type 'List' is not a subtype of type 'User'" 使用 StreamProvider 从 Firestore 检索数据时。 可以使用 .cast() 或 List.from() 对 'User' 中的数据强制执行类型安全,但这对断言没有影响。即使在 'User' 中将有问题的列表定义为动态也不会更改错误。
我已经广泛阅读了这方面的内容,例如 Github issue, typesafe Dart, and
最小代码示例
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: StreamProvider<User>.value(
value: userData,
builder: (context, snapshot) {
return MyHomePage(title: 'Demo Error');
}
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final User userData = Provider.of<User>(context) ?? []; // This asserts at runtime
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$userData.name',
),
],
),
),
);
}
}
User _getUserFromSnapshot(DocumentSnapshot snapshot){
List<String> categoriesFromDb = (snapshot.data['categories'] as List).cast<String>(); // Cast does not work
return User(uid: '8GX2aGVn0GTrwLMxSZgx6STdnnA3',
name: snapshot.data['name'],
email: snapshot.data['email'],
phone: snapshot.data['phoneNumber'],
categories: categoriesFromDb,
surname: snapshot.data['surname'],
);
}
Stream<User> get userData{
return Firestore.instance.collection('users')
.document('8GX2aGVn0GTrwLMxSZgx6STdnnA3')
.snapshots().map<User>(_getUserFromSnapshot);
}
class User {
final String uid;
final String name;
final String surname;
final String phone;
final String email;
final List<String> categories;
User({this.uid, this.name, this.surname, this.email, this.phone, this.categories})
: super();
}
重现步骤:
-> 使用 StreamProvider 从 Firestore 集合中检索字符串数组。
-> 将 Firestore 数据映射到自定义类型('User' 在我的例子中)。
-> Flutter 在运行时断言。
发生这种情况是因为初始统计没有数据,所以它是 returns 列表,但您正试图将其分配给用户类型,因为您正面临此错误。
您可以通过检查运行时类型来解决,如下所示。
final User userData = Provider.of<User>(context).runtimeType == User
? Provider.of<User>(context)
: null;