在尝试从子窗口小部件获取当前用户时遇到问题。登录时,如果我从AuthProvider print
可以看到响应。但是,当我尝试从子窗口小部件获取currentUser时,该值为null。
主要
@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(),
},
),
),
);
}
}
AuthProvider
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());
}
}
}
UsersProvider
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;
提前谢谢!
答案 0 :(得分:1)
您在loginUser内部创建的UsersProvider实例仅存在于该方法的范围内。重构方法以返回响应,然后使用它来更新提供程序。
var response = await authProvider.loginUser(loginData);
await Provider.of<UsersProvider>(context).getUserById(response.user.uid);
然后,当您调用当前用户时,它将是将要更新的同一实例。