What Does WidgetsFlutterBinding.ensureInitialized() do?

FirebaseFlutterDart

Firebase Problem Overview


I am trying to use the Firebase package with the below line of code.

I really want to know what this line of code actually does?

The official documentation didn't help me much. Can someone explain me, please?

Code snippet

Firebase Solutions


Solution 1 - Firebase

You have to use it, in this way:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

enter image description here

https://flutter.dev/docs/resources/architectural-overview#architectural-layers

The above image is the architecture layers of Flutter, the WidgetFlutterBinding is used to interact with the Flutter engine. Firebase.initializeApp() needs to call native code to initialize Firebase, and since the plugin needs to use platform channels to call the native code, which is done asynchronously therefore you have to call ensureInitialized() to make sure that you have an instance of the WidgetsBinding.

From the docs:

>Returns an instance of the WidgetsBinding, creating and initializing it if necessary. If one is created, it will be a WidgetsFlutterBinding. If one was previously initialized, then it will at least implement WidgetsBinding.

>You only need to call this method if you need the binding to be initialized before calling runApp.


From the source code:

  @override
  Future<FirebaseAppPlatform> initializeApp(
      {String name, FirebaseOptions options}) async {
    if (name == defaultFirebaseAppName) {
      throw noDefaultAppInitialization();
    }

    // Ensure that core has been initialized on the first usage of
    // initializeApp
    if (!isCoreInitialized) {
      await _initializeCore();
    }

    // If no name is provided, attempt to get the default Firebase app instance.
    // If no instance is available, the user has not set up Firebase correctly for
    // their platform.
    if (name == null) {
      MethodChannelFirebaseApp defaultApp =
          appInstances[defaultFirebaseAppName];

      if (defaultApp == null) {
        throw coreNotInitialized();
      }

      return appInstances[defaultFirebaseAppName];
    }

    assert(options != null,
        "FirebaseOptions cannot be null when creating a secondary Firebase app.");

    // Check whether the app has already been initialized
    if (appInstances.containsKey(name)) {
      throw duplicateApp(name);
    }

    _initializeFirebaseAppFromMap(await channel.invokeMapMethod(
      'Firebase#initializeApp',
      <String, dynamic>{'appName': name, 'options': options.asMap},
    ));

    return appInstances[name];
  }

The invokeMapMethod will invoke a method on the above channel with the specified arguments, which will then call the initializeApp() method in the native code, https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_core/firebase_core/android/src/main/java/io/flutter/plugins/firebase/core/FlutterFirebaseCorePlugin.java#L227


There are also different ways to initialize Firebase, which you can check here:

https://stackoverflow.com/questions/63492211/no-firebase-app-default-has-been-created-call-firebase-initializeapp-in

In the other ways we do not call WidgetsFlutterBinding.ensureInitialized() since the runApp() function calls it internally:

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

https://github.com/flutter/flutter/blob/bbfbf1770c/packages/flutter/lib/src/widgets/binding.dart#L1012

Solution 2 - Firebase

A simple answer is that if Flutter needs to call native code before calling runApp

WidgetsFlutterBinding.ensureInitialized();

makes sure that you have an instance of the WidgetsBinding, which is required to use platform channels to call the native code.

> You only need to call this method if you need the binding to be > initialized before calling runApp.

Solution 3 - Firebase

A simple answer, you need to use this line, if your main function uses async keyword because you use await statement inside it.

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences prefs = await SharedPreferences.getInstance(); // just an example
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbhishek GhimireView Question on Stackoverflow
Solution 1 - FirebasePeter HaddadView Answer on Stackoverflow
Solution 2 - FirebaseJaveed IshaqView Answer on Stackoverflow
Solution 3 - FirebaseMostafa MahmoudView Answer on Stackoverflow