简体   繁体   中英

Flutter multiprovider and consumer getting null in child widget

Im having issues trying to get the current user from a child widget. When I login I can see the response if I print from AuthProvider. However, when I try to get the currentUser from a child widget the value is null.

  1. Login in.
  2. Calling query from UsersProvider.
  3. setting the currentUser variable in said provider.
  4. go back to AuthProvider and finish login in the user.

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



}

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


}

Profile Widget

 Widget build(BuildContext context) {
    print('build profile widget');

    final currentUser = Provider.of<UsersProvider>(context).currentUser;
    print(currentUser);

I get null from here when my "Profile" widget executes final currentUser = Provider.of<UsersProvider>(context).currentUser;

Thank you in advance !

The instance of UsersProvider that you create inside of loginUser exists only in the scope of that method. Refactor the method to return the response and then use it to update the provider.

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

Then when you call the current user it'll be the same instance that will be updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM