How can I add a splash screen to my Flutter app when having a routemaster package?

219 Views Asked by At

Newbie programmer and first time asking here. Hello!

I have made a Flutter project and have used routemaster to decide whether the user is logged in or no; if Firebase recognizes the user and has data then the user should go to home screen, and if there is no data then they should be redirected to login screen.

I want to have a splash screen for two reasons: firstly, it is nice to show the logo for a few seconds and secondly because I have this same problem.

when I open my app it shows the login screen for one or two seconds until the app knows whether thre is data or not, and I am afraid if users have a slow internet connection it might appear even longer on their screens.

main.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_first_flutter_app/core/common/error_text.dart';
import 'package:my_first_flutter_app/core/common/loader.dart';
import 'package:my_first_flutter_app/features/auth/controller/auth_controller.dart';
import 'package:my_first_flutter_app/firebase_options.dart';
import 'package:my_first_flutter_app/models/user_model.dart';
import 'package:my_first_flutter_app/router.dart';
import 'package:my_first_flutter_app/theme/pallete.dart';
import 'package:routemaster/routemaster.dart';

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

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

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {
  UserModel? userModel;

  void getData(WidgetRef ref, User data) async {
    userModel = await ref
        .watch(authControllerProvider.notifier)
        .getUserData(data.uid)
        .first;
    ref.read(userProvider.notifier).update((state) => userModel);
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return ref.watch(authStateChangeProvider).when(
          data: (data) => MaterialApp.router(
            debugShowCheckedModeBanner: false,
            title: 'My Flutter App',
            theme: ref.watch(themeNotifierProvider),
            routerDelegate: RoutemasterDelegate(
              routesBuilder: (context) {
                if (data != null) {
                  getData(ref, data);
                  if (userModel != null) {
                    return loggedInRoute;
                  }
                }
                return loggedOutRoute;
              },
            ),
            routeInformationParser: const RoutemasterParser(),
          ),
          error: (error, stackTrace) => ErrorText(error: error.toString()),
          loading: () => const Loader(),
        );
  }
}

router.dart

import 'package:flutter/material.dart';
import 'package:my_first_flutter_app/features/auth/screen/login_screen.dart';
import 'package:my_first_flutter_app/features/home/screens/home_screen.dart';
import 'package:routemaster/routemaster.dart';

final loggedOutRoute = RouteMap(routes: {
  '/': (_) => const MaterialPage(child: LoginScreen()),
});

final loggedInRoute = RouteMap(routes: {
  '/': (_) => const MaterialPage(child: HomeScreen()),
});

I don't put more code here so as not to clutter the question. If you need the login screen or home screen, or other files, I can put it below.

I tried to use the answer linked in my question. I also tried to have to splash screens named SplashScreenToHome and SplashScreenToLogin (both blank pages and would redirect to home and login screens respectively). Then I modified router.dart to redirect to these two screens that would redirect automatically to their respective screens after two seconds. It did work when the user was signed in (when Firebase had data the router would redirect to SplashScreenToHome which would automatically redirect to HomeSCreen). However, when there was no data, the router would redirect to SplashScreenToLogin, but this would not redirect to LoginScreen.

This was a workaround that I tried but my intuition tells me this is not a good solution. But in a programming POV I am inexperienced and don't know.

Thanks in advance. Happy coding!

1

There are 1 best solutions below

2
Rahul On

You can use following package

https://pub.dev/packages/flutter_native_splash

This will generate code required for your splash screen on supported platforms.