1

In my Flutter app, I am using Firebase auth for the authentication of users. I am successfully able to direct the user to a specific page based on the user's auth state (Signup page if they have not signed up before, and home page if they are authenticated). However, I have an onboarding form I want users to go through after signing up and before using the app. Currently, I have a hasOnBoarded property in my database and if Firebase auth has successfully authentication the user, I make a call to the database for user data. Once the comes back I check the hasOnBoarded property to determine if they should be directed to the onboarding screen or the Home Screen. The problem I'm having is that while the user data has been successfully retrieved, they app doesn't rebuild and thus they are sent to the wrong screen (If I hot reload it does update to the correct screen). I am using a FutureBuilder to accomplish this, and I'm wondering if there is a better way. I'm also using riverpod to manage global state (which is where the user is stored).

main.dart class AppRoot extends ConsumerWidget { const AppRoot({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      ...
      initialRoute: '/loading',
      routes: {
        '/loading': (context) => const LoadingScreen(),
        '/welcome': (context) => const WelcomeScreen(),
        '/onboarding': (context) => const OnBoardingScreen(),
        '/home': (context) => const HomeScreen(),
        ...
      },
    );
  }
}

loading_screen.dart

class LoadingScreen extends ConsumerStatefulWidget {
  const LoadingScreen({Key? key}) : super(key: key);

  @override
  ConsumerState<LoadingScreen> createState() => _LoadingScreenState();
}

class _LoadingScreenState extends ConsumerState<LoadingScreen> {
  @override
  Widget build(BuildContext context) {
    final firebaseUser = ref.watch(authRepostoryProvider).getCurrentUser();
    final userExists = ref.watch(userProvider).initialize(firebaseUser?.uid);

    return FutureBuilder(
      future: userExists,
      builder: ((context, snapshot) {
        print("FutureBuilder: ${snapshot.data}");

        switch (snapshot.data) {
          case "no_user":
            return const WelcomeScreen();
          case "has_not_on_boarded":
            return const OnBoardingScreen();
          case "has_on_boarded":
            return const HomeScreen();
          default:
            return Container(
              color: Colors.white,
              child: const Center(
                child: Text("Loading..."),
              ),
            );
        }
      }),
    );
  }
}
Garrett
  • 1,576
  • 4
  • 27
  • 51

0 Answers0