imgkl
imgkl

Reputation: 1082

Sometimes widgets not rendering in production builds

Sometimes the widget doesn't render properly. This only happens on the release build irrespective of the platform OS. Not only texts, sometimes other widgets like container, images won't get rendered either. This "blank state" occurs irrespective of the app's life cycle, meaning this happens both when the app is in the background and comes foreground or opened freshly. I can work around in the app normally without any issues but can't see any widgets which I'm supposed to see. We found there are multiple rebuilds happening in the stateful widget which is responsible for the checking and routing the users according to their login status.

Anything wrong in this method?

//initializations (state variable)

Widget widgetToRender = Splash();
var _firestore;
bool isLoading = false;
StreamSubscription userProfileSubscription;

//initalize function

void _intialise(BuildContext context) async {
if (isLoading) {
  return;
}
_firestore = Provider.of<FirestoreService>(context);
userProfileSubscription = _firestore.userProfile.listen((userProfile) {
  this.setState(() {
    isLoading = true;
    widgetToRender = App();
  });
});
}

//build method

@override
Widget build(BuildContext context) {
if (widget.userSnapshot.connectionState == ConnectionState.active) {
  if (widget.userSnapshot.hasData) {
    _intialise(context);
  } else {
     setState((){
widgetToRender = AuthLanding();
})
  }
}

return widgetToRender;
}

enter image description here

Upvotes: 0

Views: 1000

Answers (2)

bizz84
bizz84

Reputation: 2262

Flutter is a declarative framework. You're going against it when you declare widgets like this:

Widget widgetToRender = Splash();

Also, you shouldn't call methods that execute imperative code from your build method:

_intialise(context);

My suggestion is to completely remove this code:

Widget widgetToRender = Splash();
var _firestore;

And rewrite things in a declarative manner. One way to do that is to use a StreamBuilder, and use its builder to return the widgets you want.

Addressing this may solve your rendering problems.

EDIT: step 1 would probably be to remove all imperative code and state variables in the build method:

@override
Widget build(BuildContext context) {
  if (widget.userSnapshot.connectionState == ConnectionState.active) {
    if (widget.userSnapshot.hasData) {
      return App();
    } else {
      return AuthLanding();
    }
  }
  return Scaffold(body: CircularProgressIndicator());
}

Upvotes: 1

Lohit Rachakonda
Lohit Rachakonda

Reputation: 64

The load lag is because you are only working with widget.userSnapshot.connectionState == ConnectionState.active you will need to add progress indicators as the response from firestore depends on the network status of the user. Please let me know if that helps.

Upvotes: 0

Related Questions