Flutter multiprovider 和 consumer 在子 widget 中获取 null

Flutter multiprovider and consumer getting null in child widget

我在尝试从子窗口小部件获取当前用户时遇到问题。当我登录时,如果我 print 来自 AuthProvider,我可以看到响应。但是,当我尝试从子小部件获取 currentUser 时,值为空。

  1. 登录。
  2. 正在从 UsersProvider 调用查询。
  3. 在所述提供者中设置 currentUser 变量。
  4. 返回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(),
          },
        ),
      ),
    );
  }
}

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" 小部件执行时,我从这里得到 null final currentUser = Provider.of<UsersProvider>(context).currentUser;

提前致谢!

您在 loginUser 中创建的 UsersProvider 实例仅存在于该方法的范围内。将方法重构为 return 响应,然后使用它来更新提供程序。

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

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