Reputation: 156
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'),
),
],
);
}
}
Upvotes: 28
Views: 104901
Reputation: 11219
If you are using a static make sure that it is not already initialized (singleton pattern with nullable variable) or removed the "static" keyword.
Switching from
static late final ScrollController scrollController;
to
late final ScrollController scrollController;
got rid of my error.
Upvotes: 0
Reputation: 21
As i was facing the same problem i used the Future Builder the snapshot.data cant be null to handle this just use if block (snapshot.data==null) then return container with child cneter Text('Loading') until future completes screen will show loading and then will display dataSolution
Upvotes: 1
Reputation: 95
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;
Upvotes: 3
Reputation: 1906
For LateInitializationError, Simply use int? count;
instead of late int count;
Upvotes: 3
Reputation: 27237
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.
Upvotes: 59
Reputation: 7
I'm very new to flutter, but this worked for me.
@override
void initState() {
// TODO: implement initState
super.initState();
findNameAndEmail().whenComplete(() {
setState(() {});
});
}
Upvotes: -1
Reputation: 3648
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
.
Upvotes: 6