0

I have a simple app from which a user can login and on logging in, a token is generated and stored on the device.

When the app starts, the following code below runs.

import 'package:coolkicks/screens/authpage.dart';
import 'package:coolkicks/screens/homescreen.dart';

import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:logger/logger.dart';

class Authenticate extends StatefulWidget {
  @override
  _AuthenticateState createState() => _AuthenticateState();
}

class _AuthenticateState extends State<Authenticate> {
  final storage = new FlutterSecureStorage();
  var log = Logger();
  bool authenticated = false;

  void checkToken() async {
    String token = await storage.read(key: 'token');
    if (token == null || token.length == 0) {
      authenticated = false;
    
    } else {
      authenticated = true;
      print(token);
      log.d(token);

      log.i(token);
    
    }
  }

  @override
  Widget build(BuildContext context) {
    //check if Authenticated or Not
    //return either Products Home Screen or Authentication Page
    //If token exists, return Home screen
    //Else return authpage

    checkToken();
    
    if(authenticated) {
      return HomeScreen();
    }
    else {
      return AuthPage();
    }

  }
}

My issue is that retrieving the token returns a future and takes some time to execute.
So it always returns the default authenticated = false

2 Answers 2

2

You should use FutureBuilder

    FutureBuilder<String>(
      future: storage.read(key: 'token'),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          final token = snapshot.data;

          if (token == null || token.length == 0) {
            return HomeScreen();
          } else {
            return AuthPage();
          }
        }

        if (snapshot.hasError) return WidgetThatShowsError();

        // by default show progress because operation is async and we need to wait for result
        return CircularProgressIndicator();
      },
    );
Sign up to request clarification or add additional context in comments.

Comments

1

Don't do this. build should be idempotent. You should call checkToken() in initState. Then you can either use setState or you use a FutureBuilder.

But, provided the naming, you should rather just provide a splash screen, check the condition and navigate to either screen, instead of using 1 route for both screens.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.