简体   繁体   中英

Flutter app stuck sometimes on the Splash screen

The app freezes on Android and iOS on the Splash screen when the app is not used for some time, like multiple days, or sometimes when I resume the recent apps, instead of opening the app on the icon tap.

It just displays a splash screen with the app being black (since I have the dark theme) and an app icon and it sticks there.

The only logic that I have is to init Firebase and to check if user is logged in.

Here is the main.dart:

///Receive message when app is in background solution for on message
Future<void> backgroundHandler(RemoteMessage message) async {
  print('Handling a background message ${message.messageId}');
  print('Content of message: ' + message.toString());
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  configureInjections();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  FirebaseMessaging.onBackgroundMessage(backgroundHandler);
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MultiBlocProvider(
        providers: [
          BlocProvider(create: (context) => getIt<SplashScreenCubit>()),
          BlocProvider(create: (context) => getIt<HomeCubit>()),
          BlocProvider(create: (context) => getIt<LogInCubit>()),
          BlocProvider(create: (context) => getIt<SettingsCubit>())
        ],
        child: OverlaySupport(
          child: MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'SAY',
            theme: appTheme,
            home: SplashScreenPage(),
          ),
        ),
      );
}

Here is the Splash page:

class SplashScreenPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => getIt<SplashScreenCubit>()..isUserAuthenticated(),
      child: BlocConsumer<SplashScreenCubit, SplashScreenState>(
          listener: (context, state) {
            if (state is Authenticated) {
              PageNavigator.navigateAndRemoveHistory(context, HomePage());
            }
            if (state is Unauthenticated) {
              PageNavigator.navigateAndRemoveHistory(context, LogInPage());
            }
            if (state is SplashError) {
              PageNavigator.navigateAndRemoveHistory(context, LogInPage());
            }
          },
          builder: (context, state) => SplashScreenContent()),
    );
  }
}

class SplashScreenContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Scaffold(
        body: Container(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          color: AppColors.primaryColor,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Expanded(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text('SAY', style: Theme.of(context).textTheme.headline1),
                    Text('Together we make it better!',
                        style: Theme.of(context)
                            .textTheme
                            .headline6!
                            .copyWith(color: AppColors.whiteColor),
                        textAlign: TextAlign.center),
                  ],
                ),
              ),
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [Image.asset(SvgIcons.splashScreenLogo)],
                ),
              )
            ],
          ),
        ),
      );
}

Here is the cubit:

@injectable
class SplashScreenCubit extends Cubit<SplashScreenState> {
  final IsUserAuthenticatedUseCase _isUserAuthenticatedUseCase;

  SplashScreenCubit(this._isUserAuthenticatedUseCase) : super(Initial());

  Future<void> isUserAuthenticated() async {
    print("Called isUserAuthenticated on the splash screen");
    try {
      var isUserAuthenticated = await _isUserAuthenticatedUseCase.execute(NoParams());
      return isUserAuthenticated ? emit(Authenticated()) : emit(Unauthenticated());
    } catch (e) {
      emit(Unauthenticated());
    }
  }
}

Here is the call to the use case and repository:

  @override
  Future<bool> isAuthenticated() {
    try {
      var currentUser = _firebaseAuth.currentUser;
      return Future.value(currentUser != null && currentUser.emailVerified);
    } catch (e) {
      return Future.value(false);
    }
  }

Okay try this in your main.dart . First I'm gonna use StreamBuilder and the Firebase method userChanges to check the auth state :

home: StreamBuilder(
          stream: FirebaseAuth.instance.userChanges(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.active) {
              if (snapshot.hasData) {
                return HomePage();
              } else if (snapshot.hasError) {
                return Center(
                  child: Text('${snapshot.error}'),
                );
              }
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
            return LogInPage();
          },
        ), 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM