flutter: LateInitializationError: Field 'name' has not been initialized

Viewed 44798

Error: Runner[463:34314] flutter: LateInitializationError: Field 'name' has not been initialized.

I recently updated to using firebase core and nullsafety and made some changes to my code that I don't quite understand, I'm new to programming here. Any way, I've tried reading this similar thread here about it but I still don't quite grasp it. I understand that I am not using name properly in the initstate most likely but that is as much as I understand. Can someone please provide an example code of what's needed to solve for the error below?

2021-04-10 17:59:41.331476-0700 Runner[463:34314] flutter: LateInitializationError: Field 'name' has not been initialized.

class MyService extends StatefulWidget {
  @override
  _MyServiceState createState() => _MyServiceState();
}

class _MyServiceState extends State<MyService> {
  late String name, email;
  Widget currentWidget = BackgroundBetcher();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    findNameAnEmail();
  }

  Future<Null> findNameAnEmail() async {
    await Firebase.initializeApp().then((value) async {
      FirebaseAuth.instance.authStateChanges().listen((event) {
        setState(() {
          name = event!.displayName!;
          email = event.email!;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: MyStyle().primaryColor,
      ),
      drawer: buildDrawer(),
      body: currentWidget,
    );
  }

  Drawer buildDrawer() {
    return Drawer(
      child: Stack(
        children: [
          Column(
            children: [
              buildUserAccountsDrawerHeader(),
              buildListTileShowCartoonList(),
              buildListTileInformation(),
            ],
          ),
          buildSignOut(),
        ],
      ),
    );
  }

  ListTile buildListTileShowCartoonList() {
    return ListTile(
      leading: Icon(
        Icons.face,
        size: 36,
      ),
      title: Text('Manual Location Update'),
      subtitle: Text('Send a single location update'),
      onTap: () {
        setState(() {
          currentWidget = PageWidget();
        });
        Navigator.pop(context);
      },
    );
  }

  ListTile buildListTileInformation() {
    return ListTile(
      leading: Icon(
        Icons.perm_device_info,
        size: 36,
      ),
      title: Text('Background Location Fetch Log'),
      subtitle: Text('History of recorded locations'),
      onTap: () {
        setState(() {
          currentWidget = BackgroundBetcher();
        });
        Navigator.pop(context);
      },
    );
  }

  UserAccountsDrawerHeader buildUserAccountsDrawerHeader() {
    return UserAccountsDrawerHeader(
      decoration: BoxDecoration(
        image: DecorationImage(
            image: AssetImage('images/wall.jpg'), fit: BoxFit.cover),
      ),
      accountName: MyStyle().titleH3(name),
      accountEmail: MyStyle().titleH3(email),
      currentAccountPicture: Image.asset('images/logo.png'),
    );
  }

  Column buildSignOut() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        ListTile(
          onTap: () async {
            await Firebase.initializeApp().then((value) async {
              await FirebaseAuth.instance.signOut().then((value) =>
                  Navigator.pushNamedAndRemoveUntil(
                      context, '/authen', (route) => false));
            });
          },
          tileColor: MyStyle().darkColor,
          leading: Icon(
            Icons.exit_to_app,
            color: Colors.white,
            size: 36,
          ),
          title: MyStyle().titleH2White('Sign Out'),
          subtitle: MyStyle().titleH3White('Sign Out & Go to Authen'),
        ),
      ],
    );
  }
}
5 Answers

You should be checking for nullable for the variable name. So, Use:

String? name;

instead of:

late String name

Late means,

I promise I will initialize this variable later

but this promise doesn't mean a thing when using that variable inside the build method.

findNameAnEmail is an asynchronous method, so, while it's called in initState, Flutter does not wait for it to complete before build is called. This results in your late fields being accessed before they are set.

In order to wait for a Future to complete before building, consider using FutureBuilder.

For LateInitializationError, Simply use int? count; instead of late int count;

I had the same problem of lateInitializationError I find out to use ? to avoid it. if some one is facing this problem instead of late try ?.

For Example:

Gender? selectedGender;

I'm very new to flutter, but this worked for me.

@override
void initState() {
    // TODO: implement initState
    super.initState();

    findNameAndEmail().whenComplete(() {
        setState(() {});
    });
}
Related