Closed domesticmouse closed 3 years ago
/cc @kroikie FYI
I can reproduce the issue This solves it
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
I'd prefer not to promote WidgetsFlutterBinding.ensureInitialized();
if at all possible =)
An idea is to add some form of widget to the firebase_auth
package that handles initialization along the lines of the following:
class FirebaseInit extends StatefulWidget {
FirebaseInit({@required this.child});
final Widget child;
@override
_FirebaseInitState createState() => _FirebaseInitState();
}
class _FirebaseInitState extends State<FirebaseInit> {
bool _initialized = false;
String _error;
void initializeFlutterFire() async {
try {
await Firebase.initializeApp();
setState(() {
_initialized = true;
});
} catch (err) {
setState(() {
_error = '$err';
});
}
}
@override
void initState() {
super.initState();
initializeFlutterFire();
}
@override
Widget build(BuildContext context) {
if (_error != null) {
return Center(child: Text(_error));
}
if (!_initialized) {
return Center(child: CircularProgressIndicator());
}
return widget.child;
}
}
The above is just a sketch, and I'm sure that we could harden it (like, say, logging the error message instead of splatting it to screen).
Hey @ditman, am I being over zealous by trying to avoid WidgetsFlutterBinding.ensureInitialized();
?
Hey @ditman, am I being over zealous by trying to avoid
WidgetsFlutterBinding.ensureInitialized();
?
@domesticmouse not sure, but I had similar doubts earlier :) I checked the docs and it seems it can be used exactly for this purpose:
You only need to call this method if you need the binding to be initialized before calling runApp.
(I normally had only seen this used within tests)
It'd be awesome to figure out what "asynchronous" thing your Future is losing its race against and the FutureBuilder
case Just Workedâ„¢, I've used a similar approach to make a deferred-loaded app before (note how the ensureInitialized was also added there :/).
I remember WidgetsFlutterBinding.ensureInitialized();
becoming required in various places in about the 1.17 timeframe for various usecases. I'm happy to roll back my stance and just add the ensure initialized call to the sample in the documentation to prevent people hitting it and getting confused at the error.
I'm unsure who to chat with about debugging why this is required. I'm guessing it is something deep in the FFI bindings =)
What reservations do you have against calling WidgetsFlutterBinding.ensureInitialized()
? It's exactly what runApp
does internally as well, there really shouldn't be any harm in doing so.
@goderbauer personally, I had only seen ensureInitialized
used in tests before, never had seen a "normal" app calling it directly (but I didn't find anything in the docs advising against it).
Okiday, we just had a meeting on this and calling ensureInitialized
in main before runApp
is totally ok to do. So if we can get the sample updated as @TahaTesser suggested in https://github.com/FirebaseExtended/flutterfire/issues/3490#issuecomment-688816602 that'd be fantastic =)
I suspect this is the affected file: https://github.com/FirebaseExtended/flutterfire/blame/master/docs/overview.mdx#L67
I'm still a bit confused here. Wouldn't this effect other plugins which call a native method immediately? What is FlutterFire doing which causes this issue specifically (when you don't add WidgetsFlutterBinding.ensureInitialized();
)?
I'm attempting to implement the Initializing Flutterfire FutureBuilder approach with Flutter 1.20 and hitting the following exception:
My
main.dart
looks like this:While I can work around this by adding
WidgetsFlutterBinding.ensureInitialized();
tomain
, that is an ugly hack. It'd make more sense to only promote theStatefulWidget
approach.