当我尝试更新用户配置文件时,我一直在调用 null 的 getter
I keep getting getters called on null when I try to update the user profile
你好,我是 flutter 的新手,我正在尝试为登录的用户做一个简单的用户配置文件屏幕,但我遇到了一些错误,第一个是当我尝试使用 StreamBuilder() 其中流没有从 UserProvider() 中的 getter 获取任何数据(那是我把我的 BL) 它一直说 getCurrentUserData() 被调用为空,所以我直接将它连接到 UserService() 并且有效,但是当我尝试编辑用户信息并通过 initState() 向 TextFormField() 填充用户数据时 并让 fullNameController 从 UserModel() 获取数据返回的错误它一直说 fullName 是在 null 上调用的!我该如何解决这个问题,谁能指出我哪里出错了?
P.S 我正在关注这个 tutorial 来构建这个。
我的 StreamBuilder() 连接到 UserProvider:
return StreamBuilder<UserModel>(
stream: userProviderData.getCurrentUserData(),
builder: (context, snapshot) {})
我的 StreamBuilder() 直接连接到 UserService:
Directly connected to UserService
return StreamBuilder<UserModel>(
stream: userService.getCurrentUser(),
builder: (context, snapshot) {})
UserService() class:
// Get User
Stream<UserModel> getCurrentUser() {
return _db.collection('users').doc(_auth.currentUser.uid).snapshots().map(
(user) => UserModel.fromJson(user.data()),
);
}
// Add or Update User info
Future<void> saveUser(UserModel user) {
final _options = SetOptions(merge: true);
return _db.collection('users').doc(user.userId).set(user.toMap(), _options);
}
UserProvider() class:
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return;
});
class UserProvider with ChangeNotifier {
final userService = UserService();
String _userId;
String _fullName;
// Getters
String get userId => _userId;
String get fullName => _fullName;
Stream<UserModel> get getCurrentUserData => userService.getCurrentUser();
// Setters
set changeFullName(String fullName) {
_fullName = fullName;
notifyListeners();
}
// Functions
void loadUser(UserModel userModel) {
_userId = userModel.userId;
_fullName = userModel.fullName;
}
void updateUser() {
final _currentUser = UserModel(
userId: _userId,
fullName: _fullName,
);
userService.saveUser(_currentUser);
}
}
EditProfileScreen():
class EditProfileScreen extends StatefulWidget {
const EditProfileScreen({this.userModel});
final UserModel userModel;
@override
_EditProfileScreenState createState() => _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final _fullNameController = TextEditingController();
final _validator = Validator();
@override
void dispose() {
_fullNameController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
final userStream = context.read(userProvider);
if (widget.userModel != null) {
// Edit
_fullNameController.text = widget.userModel.fullName;
userStream.loadUser(widget.userModel);
}
}
@override
Widget build(BuildContext context) {
final userData = context.read(userProvider);
return Scaffold(
body: Column(
children: [
TextFormFiled(
hintText: ‘Full name’,
keyboardType: TextInputType.name,
controller: _fullNameController,
validator: (value) => _validator.validateFullName(
value,
),
onChanged: (value) {
userData.changeFullName = value;
debugPrint(value);
}
),
ElevatedButton(
onPressed: () {
userData.updateUser();
Navigator.of(context).pop();
},
child: const Text(‘Save’),
),
],
),
);
}
}
你有没有忘记return什么?
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return; //return a UserProvider()
});
你好,我是 flutter 的新手,我正在尝试为登录的用户做一个简单的用户配置文件屏幕,但我遇到了一些错误,第一个是当我尝试使用 StreamBuilder() 其中流没有从 UserProvider() 中的 getter 获取任何数据(那是我把我的 BL) 它一直说 getCurrentUserData() 被调用为空,所以我直接将它连接到 UserService() 并且有效,但是当我尝试编辑用户信息并通过 initState() 向 TextFormField() 填充用户数据时 并让 fullNameController 从 UserModel() 获取数据返回的错误它一直说 fullName 是在 null 上调用的!我该如何解决这个问题,谁能指出我哪里出错了?
P.S 我正在关注这个 tutorial 来构建这个。
我的 StreamBuilder() 连接到 UserProvider:
return StreamBuilder<UserModel>(
stream: userProviderData.getCurrentUserData(),
builder: (context, snapshot) {})
我的 StreamBuilder() 直接连接到 UserService:
Directly connected to UserService
return StreamBuilder<UserModel>(
stream: userService.getCurrentUser(),
builder: (context, snapshot) {})
UserService() class:
// Get User
Stream<UserModel> getCurrentUser() {
return _db.collection('users').doc(_auth.currentUser.uid).snapshots().map(
(user) => UserModel.fromJson(user.data()),
);
}
// Add or Update User info
Future<void> saveUser(UserModel user) {
final _options = SetOptions(merge: true);
return _db.collection('users').doc(user.userId).set(user.toMap(), _options);
}
UserProvider() class:
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return;
});
class UserProvider with ChangeNotifier {
final userService = UserService();
String _userId;
String _fullName;
// Getters
String get userId => _userId;
String get fullName => _fullName;
Stream<UserModel> get getCurrentUserData => userService.getCurrentUser();
// Setters
set changeFullName(String fullName) {
_fullName = fullName;
notifyListeners();
}
// Functions
void loadUser(UserModel userModel) {
_userId = userModel.userId;
_fullName = userModel.fullName;
}
void updateUser() {
final _currentUser = UserModel(
userId: _userId,
fullName: _fullName,
);
userService.saveUser(_currentUser);
}
}
EditProfileScreen():
class EditProfileScreen extends StatefulWidget {
const EditProfileScreen({this.userModel});
final UserModel userModel;
@override
_EditProfileScreenState createState() => _EditProfileScreenState();
}
class _EditProfileScreenState extends State<EditProfileScreen> {
final _fullNameController = TextEditingController();
final _validator = Validator();
@override
void dispose() {
_fullNameController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
final userStream = context.read(userProvider);
if (widget.userModel != null) {
// Edit
_fullNameController.text = widget.userModel.fullName;
userStream.loadUser(widget.userModel);
}
}
@override
Widget build(BuildContext context) {
final userData = context.read(userProvider);
return Scaffold(
body: Column(
children: [
TextFormFiled(
hintText: ‘Full name’,
keyboardType: TextInputType.name,
controller: _fullNameController,
validator: (value) => _validator.validateFullName(
value,
),
onChanged: (value) {
userData.changeFullName = value;
debugPrint(value);
}
),
ElevatedButton(
onPressed: () {
userData.updateUser();
Navigator.of(context).pop();
},
child: const Text(‘Save’),
),
],
),
);
}
}
你有没有忘记return什么?
final userProvider = ChangeNotifierProvider<UserProvider>((ref) {
return; //return a UserProvider()
});