【问题标题】:Flutter multiprovider and consumer getting null in child widgetFlutter 多提供者和消费者在子小部件中为空
【发布时间】:2020-05-10 04:11:50
【问题描述】:

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

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



}

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&lt;UsersProvider&gt;(context).currentUser;

提前谢谢你!

【问题讨论】:

  • 你能发布更新的代码吗?比如修复后的效果如何?

标签: android ios flutter provider consumer


【解决方案1】:

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

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

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

【讨论】:

  • 非常感谢!这是我的一个愚蠢的错误,但由于某种原因我看不到它。
猜你喜欢
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多