How do I setup a database when Flutter app launches?

In your first widget that opens when the app starts

@override
void initState() {
  onStart();
}

void onStart() async {
  await loadData();  //load your data here
  Navigator.push();  //push to next screen
}

onStart will load the data asynchronously.
And when the data gets loaded push to next screen.


Well we can handle this with BLoC.

create a app_bloc.dart file and have AppBloc class as shown bellow in it:

import 'dart:async';

final appBloc =  AppBloc();

enum AppEvent{
  onStart, onAppInitialized, onStop
}

class AppBloc {
  final _appEventController = StreamController<AppEvent>.broadcast();

  Stream<AppEvent> get appEventsStream => _appEventController.stream;

  dispatch(AppEvent event) {
    switch(event) {
      case AppEvent.onStart:
        _initializeApp();
        _sinkEvent(AppEvent.onStart);
        break;
      case AppEvent.onStop:
        _dispose();
        _sinkEvent(AppEvent.onStop);
        break;
      case AppEvent.onAppInitialized:
        _sinkEvent(AppEvent.onAppInitialized);
        break;
    }
  }

  void _sinkEvent(AppEvent appEvent) => _appEventController.sink.add(appEvent);

  _dispose() {
    _appEventController.close();
  }

  void _initializeApp() async {
    await DBProvider.db.initDB();
    dispatch(AppEvent.onAppInitialized); // will execute when all initializations are complete,
  }
}

create a database.dart file and have your DBProvider class in it:

class DBProvider {
  static final DBProvider _instance = new DBProvider._internal();

  static final db = DBProvider();

  factory DBProvider() {
    return _instance;
  }

  DBProvider._internal();

  initDB() async {
    // todo initialize your database here.
  }
}

You should have your main file something like this:

import 'package:flutter/material.dart';

import 'package:st_overflow/app_bloc.dart';

void main() => runApp(App());

class App extends StatefulWidget {

  App() {
    appBloc.dispatch(AppEvent.onStart);
  }

  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {

  @override
  Widget build(BuildContext context) {
    return Launch();
  }

  @override
  void dispose() {
    appBloc.dispatch(AppEvent.onStop);
    super.dispose();
  }
}

and in your Launch Widget consume the onAppInitialize event using StreamBuilder like this:

StreamBuilder(
    stream: appBloc.appEventsStream,
    builder: (context, snapshot){
        switch (snapshot.data) {
            case AppEvent.onAppInitialized:
            // remove your Launch widget and show Screen 1 of your app (may be dashboard or something).
            break;        
        }
    },
);

Tags:

Dart

Flutter