I've been stuck for several hours with a problem on flutter. If you can help me that would be really nice.
I need to put "await" in my Widget build(BuildContext context){} but it's impossible to put "async". How to do ?
When i test void _myAsyncMethod()async{} :
CodePudding user response:
To Fix your issue you can put async in the body of method like this
Before=> Widget build(BuildContext context) {
After=> Widget build(BuildContext context) async{
Although this will not solve your problem as flutter wiill warn you as this is not the proper way to do it.
It's not a good practice to call await inside flutter's build method Because
- Generally an apps need to run a 60 frames per second on an average hence flutter's build method we'll be called over and over to re-render the ui.
- Another reason is that, doing calling await function() in build method will block your UI.
Solution
- use FutureBuilder
- call await auth.currentUser() in initState method
Another way to solve this is to use FutureBuilder
sample Code for 1
FutureBuilder(
builder: (BuildContext ctx, AsyncSnapshot<userModel> snapshot) {
if(ConnectionState.done == snapshot.connectionState) {
return Text(snapshot.data.userId);
} else {
return CircularProgressIndicator();
}
},
future: auth.currentUser(),
);
sample Code for 2(stateful widget)
late UserModel;
void initState() {
UserModel user = await auth.currentUser();
}
this is very basic code but it's enough for you to get started.
Note: I've assumed userModel
mentioned above is response type of auth.currentUser()
you can change it accordingly.
CodePudding user response:
What you want to do is not optimal but you can create a method and put your await
variable in there:
late final FirebaseUser _user;
void _myAsyncMethod()async{
_user = await auth.currentUser;
}
@override
Widget build(BuildContext context) {
_myAsyncMethod();
return Scaffold(appBar: AppBar(), body: Container());
}
CodePudding user response:
- If your are using stateful widget you can instantiate firebase auth in
initstate()
method.
class testFirless extends StatefulWidget {
var currentuseid = "";
testFirless({Key? key}) : super(key: key);
@override
_testFirlessState createState() => _testFirlessState();
}
class _testFirlessState extends State<testFirless> {
@override
Widget build(BuildContext context) {
return Container();
}
// ------------------------------------>heree
@override
Future<void> initState() async {
FirebaseAuth auth = FirebaseAuth.instance;
var user = await auth.currentUser;
if (user == null) {
widget.currentuseid = user!.uid;
} else {
print('User is signed in!');
}
}
}
- FutureBuilder
class fbuilder extends StatelessWidget {
const fbauth({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
FirebaseAuth auth = FirebaseAuth.instance;
// --------------->
return Container(child: FutureBuilder(
builder: (BuildContext ctx, AsyncSnapshot<User> snapshot) {
if (ConnectionState.done == snapshot.connectionState) {
return Text(snapshot.data.userId.toString());
} else {
return CircularProgressIndicator();
}
},
future: auth.currentUser(),
));
}
}
- in
stateless
orstateful
widget
String currentuseid="";
class fbauth extends StatelessWidget {
const fbauth({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
FirebaseAuth auth = FirebaseAuth.instance;
// ------------------------>
auth.currentUser().then((user) {
if (user == null) {
currentuseid = user!.uid;
} else {
print('User is signed in!');
}
// other logic after the user retrieval
});
return Container();
}
}
Nb: Instead of instantiating firebase auth in every widget .you must instantiate in `void main` method