Flutter在运行时抛出异常。当使用StreamProvider从Firestore检索数据时,"类型'List'不是类型'User'的子类型".类型安全可以通过.cast()或List.from()对'User'中的数据进行强制执行,但这对断言没有任何影响。即使在'User'中把违规的List定义为动态,也不能改变错误。
我已经广泛阅读了这方面的内容,像这样。Github问题, 类型安全型飞镖和 StackOverflow. 这些解决方案都无济于事,希望这里有人能帮帮我。
最小的代码示例
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集合中检索Strings数组。
-> 用StreamProvider从Firestore集合中获取一个字符串数组。
-> 将Firestore数据映射到自定义类型(在我的例子中是'User')。
-> Flutter在运行时断言。
这是发生的,因为初始统计没有数据,所以它返回List,但你正试图将其分配给User类型,因此你面临这个错误。
你可以通过检查以下的runtimeType来解决。
final User userData = Provider.of<User>(context).runtimeType == User
? Provider.of<User>(context)
: null;