我尝试建立一个个人资料类型页面,用户可以在其中查看其信息,最终我将添加功能,以便他们可以更改其数据。我正在使用Provider访问Firebase流<User>
,该流返回当前用户的UID(工作正常)。然后,该UID用于访问其<UserData>
流,但是当我尝试打印UserData().email
或任何其他数据位时,它仅返回null。代码如下:
class Profile extends StatefulWidget {
@override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamProvider<UserData>.value(
initialData: UserData.initialData(),
value: DatabaseService(uid: user.uid).userData,
child: Scaffold(
appBar: AppBar(),
drawer: NavigationDrawer(),
body: ListView(
children: <Widget>[
ListTile(
title: Text(UserData().email),
)
],
),
),
);
}
}
流本身看起来像这样:
UserData _userDataFromSnapshot(DocumentSnapshot snapshot) {
return UserData(
uid: uid,
email: snapshot.data['email'],
firstName: snapshot.data['firstName'],
lastName: snapshot.data['lastName'],
phone: snapshot.data['phone'],
dateCreated: snapshot.data['dataCreated'],
isVerified: snapshot.data['isVerified']
);
}
//User data stream
Stream<UserData> get userData {
return userDataCollection.document(uid).snapshots()
.map(_userDataFromSnapshot);
}
UserData类就是这个
class UserData {
final String uid;
final String email;
final String firstName;
final String lastName;
final String phone;
final DateTime dateCreated;
final bool isVerified;
UserData({ this.uid, this.email, this.firstName, this.lastName, this.phone, this.dateCreated, this.isVerified });
factory UserData.initialData() {
return UserData(
uid: '',
email: '',
firstName: '',
lastName: '',
phone: '',
dateCreated: null,
isVerified: null,
);
}
}
最后这是我从ListTile中得到的错误,因为UserData().email
为null,而不是字符串:
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 285 pos 10: 'data != null'
我认为数据可能无法及时加载可能是个问题,因此当Flutter尝试构建页面时,数据就不存在了,但是添加UserData.initialData
似乎没有帮助。我已经设法使用StreamBuilder使其工作,但是我不是使用这是最佳实践,还是我不应该对Provider进行所有操作,以便获得任何帮助。
谢谢
答案 0 :(得分:1)
我认为您使用了StreamProvider错误的方式。在下面的代码中,您将创建一个新的UserData对象。
ListTile(
title: Text(UserData().email),
)
这是一个示例,说明如何通过创建单独的小部件来使用StreamProvider。
class Profile extends StatefulWidget {
@override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
@override
Widget build(BuildContext context) {
return StreamProvider<UserData>.value(
initialData: UserData.initialData(),
value: DatabaseService(uid: user.uid).userData,
child: SecondWidget(),
);
}
}
class SecondWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<UserData>(context);
return Scaffold(
appBar: AppBar(),
drawer: NavigationDrawer(),
body: ListView(
children: <Widget>[
ListTile(
title: Text(user.email),
)
],
),
);
}
}