Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - onGenerateRoute with Await for auth Guard

I have a Flutter app with multiple pages, some pages require the user to be logged in, in order to access the page.

The main issue I am having is, for my kDashboardRoute I need to call an async method to check if the user is logged in and set the bool isUserLoggedIn accordingly, however, I can not call this method as it returns a future and I can not use await as the routes method can not return a future.

Any suggestions please?

Below is the code in my main.dart class

Future<void> main() async {
  // run the app
  runApp(
    MaterialApp(
      title: kAppName,
      theme: ThemeData(
        primarySwatch: Colors.green,
        primaryColor: kPrimaryColour,
      ),
      onGenerateRoute: RouteGenerator.routes,
    ),
  );
}

Below is the code in my Routes File

import 'package:flutter/material.dart';
import 'package:myapp/services/auth_service.dart';
import 'package:myapp/utilities/constants.dart';
import 'package:myapp/pages/login_page.dart';
import 'package:myapp/pages/two_step_verification.dart';
import 'package:myapp/pages/dashboard_page.dart';
import 'package:myapp/pages/error_page.dart';

class RouteGenerator {
  static Route<dynamic> routes(RouteSettings settings) {
    final args = settings.arguments;

    switch (settings.name) {
      case kLoginRoute:
        return MaterialPageRoute(builder: (_) => LoginPage());
      case kTwoStepAuthRoute:
        return MaterialPageRoute(builder: (_) => TwoStepVerification());
      case kDashboardRoute:
        // TODO: call my auth check method here which required await
        bool isUserLoggedIn = true;  // set this accordingly 
        if (isUserLoggedIn == true) {
          return MaterialPageRoute(builder: (_) => DashboardPage());
        }

        return MaterialPageRoute(builder: (_) => ErrorPage());
      default:
        return MaterialPageRoute(builder: (_) => LoginPage());
        break;
    }
  }
}
like image 490
Billy Mahmood Avatar asked Aug 05 '19 10:08

Billy Mahmood


1 Answers

As you can see onGenerateRoute must return Route, so it must be synchronous and can't use await.

I think the easiest solution for provided situation would be to create a proxy page for dashboard that will consist of FutureBuilder where you can display some progress indicator while future is in progress and update it when result is obtained.

Another option would be to use FutureBuilder again but for whole MaterialApp class.

And if future is actually quite fast (reading from shared preferences or local database) then you can try to await for future result in main function before runApp

like image 54
Mikhail Ponkin Avatar answered Sep 19 '22 05:09

Mikhail Ponkin