android - 颤振多提供者和消费者在子小部件中为空
问题描述
我在尝试从子小部件获取当前用户时遇到问题。当我登录时,如果我print
来自 AuthProvider,我可以看到响应。但是,当我尝试从子小部件获取 currentUser 时,该值为 null。
- 登录。
- 从 UsersProvider 调用查询。
- 在所述提供者中设置 currentUser 变量。
- 返回 AuthProvider 并完成用户登录。
主要的
@override
Widget build(BuildContext context) {
print('build Main');
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: AuthProvider(),
),
ChangeNotifierProvider.value(
value: UsersProvider(),
),
],
child: Consumer<AuthProvider>(
builder: (ctx, auth, _) => MaterialApp(
title: 'Wayuu',
theme: ThemeData(
primarySwatch: Colors.indigo,
accentColor: Colors.purpleAccent,
// textTheme: ThemeData.dark().textTheme.copyWith(
// title: TextStyle(
// color: Theme.of(context).accentColor,
// fontWeight: FontWeight.bold,
// fontSize: 20,
// ),
// ),
),
home: auth.isAuthenticated
? HomeState()
: FutureBuilder(
future: auth.isAuth(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? Splash()
: Login()),
routes: {
Home.routeName: (context) => Home(),
Profile.routeName: (context) => Profile(),
ForgotPassword.routeName: (context) => ForgotPassword(),
RegisterScreen.routeName: (context) => RegisterScreen(),
Favorites.routeName: (context) => Favorites(),
Podcast.routeName: (context) => Podcast(),
MyAccount.routeName: (context) => MyAccount(),
},
),
),
);
}
}
身份验证提供者
bool _userAuthenticated = false;
bool get isAuthenticated {
return _userAuthenticated;
}
Future<bool> isAuth() async {
final FirebaseUser response = await FirebaseAuth.instance.currentUser();
if (response != null) {
_userAuthenticated = true;
notifyListeners();
}
return _userAuthenticated;
}
Future<void> loginUser(Map<String, String> loginData) async {
UsersProvider usersProvider = UsersProvider();
try {
final response = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: loginData['usernameOrEmail'], password: loginData['password']);
// _currentUserId = response.user.uid;
await usersProvider.getUserById(response.user.uid);
await storeUserIdInSharePreferences(response.user.uid);
_userAuthenticated = true;
notifyListeners();
} catch (error) {
throw HttpException(error.toString());
}
}
}
用户提供者
class UsersProvider with ChangeNotifier {
Map<String, dynamic> _currentUser = {};
Map<String, dynamic> get currentUser {
return {..._currentUser};
}
Future<void> getUserById(String userId) async {
try {
QuerySnapshot querySnapshot = await Firestore.instance
.collection('users')
.where('id', isEqualTo: userId)
.getDocuments();
querySnapshot.documents.forEach((documentData) {
_currentUser = {
'id': documentData.data['id'],
'fullName': documentData.data['fullName'],
'email': documentData.data['email'],
'username': documentData.data['username'],
'profilePicture': documentData.data['profilePicture'],
'bio': documentData.data['bio'],
'instagram': documentData.data['instagram'],
'facebook': documentData.data['facebook'],
'web': documentData.data['web']
};
});
notifyListeners();
} catch (error) {
print('error from query');
print(error);
throw HttpException(error.toString());
}
}
}
个人资料小部件
Widget build(BuildContext context) {
print('build profile widget');
final currentUser = Provider.of<UsersProvider>(context).currentUser;
print(currentUser);
当我的“个人资料”小部件执行时,我从这里得到 null
final currentUser = Provider.of<UsersProvider>(context).currentUser;
先感谢您 !
解决方案
您在 loginUser 内部创建的 UsersProvider 实例仅存在于该方法的范围内。重构方法以返回响应,然后使用它来更新提供程序。
var response = await authProvider.loginUser(loginData);
await Provider.of<UsersProvider>(context).getUserById(response.user.uid);
然后,当您调用当前用户时,它将是要更新的同一个实例。
推荐阅读
- python - 在我的表单中使用 MultipleFileField() 时,FileRequiredValidator() 不起作用
- python - 当另一列增加/减少时添加状态列
- go - 从休息层的 POST 请求中排除 ID(自动增量)
- python-3.x - 如何在一个数据框中合并两列(同名)?熊猫,蟒蛇
- unicode - NSIS nsProcess 插件:始终返回“进程未运行”
- java - 静态快捷方式android不出现
- java - Apache Camel:如何查看正文以确定文件格式
- video - 索引数据包中的大型视频数据文件
- oracle - oracle 中热门查询的自动 SQL 调优顾问报告
- javascript - 如何在 NODE.JS 中保存标头?