skip to Main Content

I want to create a profil page where I just display informations from the user, but I have trouble to reach the data. When I want to use my variable user it display ‘Instance of Future<Map<String, dynamic>>’

If I put the ‘Widget build’ in async I have an error message who told me : ProfileScreen.build’ (‘Future Function(BuildContext)’) isn’t a valid override of ‘StatelessWidget.build’ (‘Widget Function(BuildContext)’).

class ProfileScreen extends StatelessWidget {
  ProfileScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final user = displayUser();
    return Scaffold(
        appBar: AppBar(
          title: Text('Profile'),
        ),
        body: Align(
          alignment: Alignment.topLeft,
          child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Align(
                  alignment: Alignment.topLeft,
                  child: Column(children: [
                    Text('Prénom :${user}nNom :nEmail :',
                        textWidthBasis: TextWidthBasis.longestLine),
                  ]),
                )
              ]),
        ),
        persistentFooterButtons: [
          SignOutButton(),
          BottomNavBar(),
        ]);
  }

  // Get user informations
  Future<Map<String, dynamic>> displayUser() async {
    final User? currentUser = FirebaseAuth.instance.currentUser;
    late final userUid = currentUser?.uid;
    late final ref = FirebaseDatabase.instance.ref();
    final resSnapshot = await ref.child('/utilisateur/' + userUid!).get();
    final Map<String, dynamic> user = {};

    if (resSnapshot.exists) {
      user['id'] = userUid;
      for (var value in resSnapshot.children) {
        String key = value.key as String;
        var val = value.value;
        user[key] = val;
      }
    } else {
      print('No data available.');
    }
    print(user); // This print display exactly the informations I want.
    return user;
  }
}


Thanks for your help.

3

Answers


  1. Your displayUser is async function and you can’t call it inside build method, you need to use FutureBuilder like this:

    @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Profile'),
          ),
          body: FutureBuilder<Map<String, dynamic>>(
            future: displayUser(),
            builder: (context, snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting:
                  return Text('Loading....');
                default:
                  if (snapshot.hasError) {
                    return Text('Error: ${snapshot.error}');
                  } else {
                    Map<String, dynamic> user = snapshot.data ?? {};
    
                    return Align(
                      alignment: Alignment.topLeft,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Align(
                            alignment: Alignment.topLeft,
                            child: Column(
                              children: [
                                Text(
                                  'Prénom :${user}nNom :nEmail :',
                                  textWidthBasis: TextWidthBasis.longestLine,
                                ),
                              ],
                            ),
                          )
                        ],
                      ),
                    );
                  }
              }
            },
          ),
          persistentFooterButtons: [
            SignOutButton(),
            BottomNavBar(),
          ],
        );
      }
    

    You can customize loading and error state to what you want.

    Login or Signup to reply.
  2. change StatelessWidget to StatefulWidget because userInteract on profileScreen,
    UserInteraction changes will show on firebase.

    class ProfileScreen extends StatefulWidget{
      ProfileScreen({super.key});
    
    Login or Signup to reply.
  3. You can load the user in the initstate and then set user using setstate

    class ProfileScreen extends StatefulWidget {
      const ProfileScreen({super.key});
    
      @override
      State<ProfileScreen> createState() => _ProfileScreenState();
    }
    
    class _ProfileScreenState extends State<ProfileScreen> {
      Map<String, dynamic>? user;
    
      @override
      void initState() {
       final User? currentUser = FirebaseAuth.instance.currentUser;
        late final userUid = currentUser?.uid;
        late final ref = FirebaseDatabase.instance.ref();
        final resSnapshot = await ref.child('/utilisateur/' + userUid!).get();
        Map<String, dynamic> temp = {};
    
        if (resSnapshot.exists) {
          temp['id'] = userUid;
          for (var value in resSnapshot.children) {
            String key = value.key as String;
            var val = value.value;
            temp[key] = val;
          }
        } else {
          print('No data available.');
        }
        print(temp);
        setState((){
        user =temp 
    });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
              child:
                  user != {} ? Text(user.toString()!) : const CircularProgressIndicator()),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search