Ulquiorra
Ulquiorra

Reputation: 45

Trying to display username on Homepage using Flutter

Using the following code, I am able to retrieve the username of the currently logged in user but when I try to display it, it displays as null.

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:localeventsapp/Screens/Login/login_screen.dart';
import 'package:localeventsapp/model/category.dart';
import 'package:localeventsapp/model/event.dart';
import 'package:localeventsapp/styleguide.dart';
import 'package:localeventsapp/ui/event_details/event_details_page.dart';
import 'package:localeventsapp/ui/homepage/form_widget.dart';
import 'package:provider/provider.dart';
import '../../app_state.dart';
import '../../authentication_service.dart';
import 'category_widget.dart';
import 'event_widget.dart';
import 'home_page_background.dart';

CollectionReference users = FirebaseFirestore.instance.collection("Users");
FirebaseAuth auth =  FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();

// String uName = getUsername(uid).toString();

String getUsername(String uid) {
  String username;
  DocumentReference documentReference = users.doc(uid);
  documentReference.get().then((snapshot) {
    username = snapshot.data()['displayName'].toString();
    print("Username is " + username);
  });
  return username;
}

class HomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ChangeNotifierProvider<AppState>(
        create: (_) => AppState(),
        child: Stack(
          children: <Widget>[
            HomePageBackground(
              screenHeight: MediaQuery.of(context).size.height,
            ),
            SafeArea(
              child: SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 32.0),
                      child: Row(
                        children: <Widget>[
                          Text(
                            "TuLink",
                            style: fadedTextStyle,
                          ),
                          Spacer(),
                        ],
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 32.0),
                      child: Text(
                        getUsername(uid).toString(),
                        style: whiteHeadingTextStyle,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 24.0),
                      child: Consumer<AppState>(
                        builder: (context, appState, _) =>
                          SingleChildScrollView(
                          scrollDirection: Axis.horizontal,
                          child: Row(
                            children: <Widget>[
                              for (final category in categories)
                                CategoryWidget(category: category),

                            ],
                          ),
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 16.0),
                      child: Consumer<AppState>(
                        builder: (context, appState, _) => Column(
                          children: <Widget>[
                            for (final event in events.where((e) => e
                                .categoryIds
                                .contains(appState.selectedCategoryId)))
                              GestureDetector(
                                onTap: () {
                                  Navigator.of(context).push(
                                    MaterialPageRoute(
                                      builder: (context) =>
                                          EventDetailsPage(event: event),
                                    ),
                                  );
                                },
                                child: EventWidget(
                                  event: event,
                                ),
                              )
                          ],
                        ),
                      ),
                    ),
                    FloatingActionButton.extended(
                     onPressed: () {
                       Navigator.push(context,
                       MaterialPageRoute(builder: (context) => FormPage()));
                     },
                     label: Text('Create'),
                     icon: Icon(Icons.create),
                     elevation: 2,
                     shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
                     backgroundColor: Color(0xFF6F35A5),
                    ),
                    ElevatedButton(
                  child: Text('Sign Out',
                      style: TextStyle(
                        color: Colors.black,
                        fontSize: 16,
                      )),
                  onPressed: () {
                    context.read<AuthenticationService>().signOut();
                    Navigator.of(context).push(MaterialPageRoute(builder: (context) => LoginScreen()));
                  }),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }


}

class CircularButton extends StatelessWidget {
  final double width;
  final double height;
  final Color color;
  final Icon icon;
  final Function onClick;

  CircularButton(
      {this.color, this.width, this.height, this.icon, this.onClick});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: color, shape: BoxShape.circle),
      width: width,
      height: height,
      child: IconButton(
        icon: icon,
        enableFeedback: true,
        onPressed: onClick,
      ),
    );
  }
}

Specifically this part :

Padding(
       padding: const EdgeInsets.symmetric(horizontal: 32.0),
       child: Text(
       getUsername(uid).toString(),
       style: whiteHeadingTextStyle,
         ),
       ),

The "getUsername(uid).toString()" portion returns a null here.

This is the getUsername method:

String getUsername(String uid) {
  String username;
  DocumentReference documentReference = users.doc(uid);
  documentReference.get().then((snapshot) {
    username = snapshot.data()['displayName'].toString();
    print("Username is " + username);
  });
  return username;
}

But print returns the name just fine. I'm kind of stumped. Any ideas?

Upvotes: 0

Views: 745

Answers (1)

Mahesh Jamdade
Mahesh Jamdade

Reputation: 20249

Just add a setState before your return statement

setState({}); /// only works in a statefulWidget
return username;

This is happening because by the time your fetch username the build method runs and the Ui is built that means username is displayed as null in the Ui, but when the username is fetched the variable has the value but its not displayed on screen because you need to redraw the widgets in order to show the updated value on the screen by calling setState thats how flutter works.I would recommend you to play around with the flutters counter app and try to add print statements and remove setState.

Although SetState might not be the best solution there are different techniques though but setState is a good place to start And then later you could move on to using widgets like ValueListenableBuilder, FutureBuilder etc

Upvotes: 1

Related Questions