Flutter多提供程序和消费者在子窗口小部件中获取null



我在尝试从子窗口小部件获取当前用户时遇到问题。当我登录时,如果我从AuthProviderprint,我可以看到响应。但是,当我尝试从一个子窗口小部件获取currentUser时,该值为null。

  1. 登录
  2. 正在从UsersProvider调用查询
  3. 在所述提供程序中设置currentUser变量
  4. 返回AuthProvider并在用户中完成登录

main

@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());
}
}

}

用户提供商

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);

当我的"Profile"小部件执行时,我从这里得到nullfinal currentUser = Provider.of<UsersProvider>(context).currentUser;

提前谢谢!

您在loginUser内部创建的UsersProvider实例仅存在于该方法的作用域中。重新构造方法以返回响应,然后使用它更新提供程序。

var response = await authProvider.loginUser(loginData); await Provider.of<UsersProvider>(context).getUserById(response.user.uid);

然后,当您调用当前用户时,它将是将被更新的同一实例。

最新更新