skip to Main Content

The project has a lot of initial initialization, without which the project will not work (logging, database initialization (floor), getIt (services), and a bunch more)

I can put all this friendly initialization into one method, let’s call it initApp()

Where is the right place to run it?

My options:

  1. In the main method, actually before runApp
void main() {
  initApp();
  runApp(const MyApp());
}
  1. Make the first home_screen, in which initialization will take place, and after initialization, transfer it to the desired screen depending on the user authentication and user role (although this processing can also be done in go_router).
    Minuses item 2, using go_router, deeplink does not work well, because we actually do not get to the home_screen
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  
  @override
  void initState() {
    super.initState();
    initApp();
    FlutterNativeSplash.remove(); // end splash
  }
  
  @override
  Widget build(BuildContext context) {
    return NextScreenForAuth();
  }
}
  1. Any other correct solution?

2

Answers


  1. Guess it depends on your situation. If the initApp function is a Future you can await it at least inside main (making main async). This wouldn’t work inside initState in your 2 solution, you would work here with a FutureBuilder or something like that.

    You can also run runApp twice where you runApp first a loading widget, do your init stuff and call after the real app. Here is an example:

    https://www.youtube.com/watch?v=S05fvqzzgzE

    Login or Signup to reply.
  2. The correct way is to follow the instructions from each package that you need to initialize.

    For example, the FlutterFire docs tells you to put the initialization inside the main method:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      runApp(MyApp());
    }
    

    You can also see the package’s example app. For example, get_it has the initialization done like this in its example app:

    GetIt getIt = GetIt.instance;
    
    void main() {
      getIt.registerSingleton<AppModel>(AppModelImplementation(),
          signalsReady: true);
    
      runApp(const MyApp());
    }
    

    If you have multiple initializations that are asynchronous and are independent from each other, you can wrap them with a Future.wait (or use the wait extension on the list):

    await Future.wait(
        [
          Hive.initFlutter(),
          dotenv.load(fileName: '.env'),
        ],
      );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search