How I use Amplify Auth with Flutter

offlineprogrammer

Offline Programmer

Posted on January 14, 2021

How I use Amplify Auth with Flutter

One of my goals this year is to publish my App KidzTokenz on Apple App Store. For that, I am planning to use Flutter and AWSAmplify.

In this post, we will integrate the Auth category into a Flutter App and run it on iOS.

Amplify Setup

I am going to use Amplify Admin UI to create the backend. Use the instruction I shared in the previous post (link below) to create a project of the name (AuthFlutter).

Configure and deploy the Authentication. We are going to use (Email) for verification.

Screen Shot 2021-01-13 at 1.24.25 PM

Project Setup

Using Terminal, create a new flutter project by running the command below


flutter create auth_for_flutter

Enter fullscreen mode Exit fullscreen mode

Next, let's open the project folder using the VS Code. Make sure the integrated terminal is in the ios folder.

Screen Shot 2021-01-12 at 1.43.06 PM

Run the following commands, and you will get a Podfile in the ios folder.


sudo gem install cocoapods

pod init

Enter fullscreen mode Exit fullscreen mode

Update the Podile as below


platform :ios, '13.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end


Enter fullscreen mode Exit fullscreen mode

In XCode, select your project in the Project Navigator and select the “Info” tab. Set the Deployment Target to at least 13.0.

Screen Shot 2021-01-12 at 2.13.21 PM

Open the App‘s pubspec.yaml and add the following dependencies below the line “sdk:flutter”.


dependencies:
  flutter:
    sdk: flutter
  amplify_core: '<1.0.0'
  amplify_auth_cognito: '<1.0.0'

Enter fullscreen mode Exit fullscreen mode

Run the command below in the in ios folder


pod install

Enter fullscreen mode Exit fullscreen mode

This is going to install the required Pods.

Screen Shot 2021-01-12 at 2.23.22 PM

Pull down the Amplify backend we created above by running the pull command from the Admin UI in the root folder of the App

Screen Shot 2021-01-13 at 4.20.06 PM

Answer the prompted questions, and once complete, you will get a confirmation as below.


Added backend environment config object to your project.
Run 'amplify pull' to sync upstream changes.

Enter fullscreen mode Exit fullscreen mode

Update the app‘s pubspec.yaml to add the image file we are going to use


# To add assets to your application, add an assets section, like this:
  assets:
     - assets/images/applogo.png

Enter fullscreen mode Exit fullscreen mode

Run the App to make sure it builds successfully

Screen Shot 2021-01-12 at 2.25.57 PM

The Implementation

We are going to use an enum for the authentication's status. Create the file below in the (lib) folder

account_screens_enum.dart


enum AccountStatus {
  sign_in,
  sign_up,
  reset_password,
  confirm_code,
  main_screen
}

Enter fullscreen mode Exit fullscreen mode

Next, let's create the widgets in (lib\widgets) folder.

sign_up.dart

To create an account.


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/account_screens_enum.dart';
import 'package:auth_for_flutter/widgets/confirm_signup.dart';
import 'package:auth_for_flutter/widgets/error_view.dart';
import 'package:flutter/material.dart';

class SignUpView extends StatefulWidget {
  final Function _displayAccountWidget;

  const SignUpView(this._displayAccountWidget);

  @override
  _SignUpViewState createState() => _SignUpViewState();
}

class _SignUpViewState extends State<SignUpView> {
  final emailController = TextEditingController();
  final passwordController = TextEditingController();
  bool _isSignedUp = false;
  DateTime signupDate;

  String _signUpError = "";
  List<String> _signUpExceptions = [];

  @override
  void initState() {
    super.initState();
  }

  void _setError(AuthError error) {
    setState(() {
      _signUpError = error.cause;
      _signUpExceptions.clear();
      error.exceptionList.forEach((el) {
        _signUpExceptions.add(el.exception);
      });
    });
  }

  void _signUp(BuildContext context) async {
    try {
      Map<String, dynamic> userAttributes = {
        "email": emailController.text.trim(),
        "preferred_username": emailController.text.trim(),
        // additional attributes as needed
      };
      SignUpResult res = await Amplify.Auth.signUp(
          username: emailController.text.trim(),
          password: passwordController.text.trim(),
          options: CognitoSignUpOptions(userAttributes: userAttributes));

      print(res.isSignUpComplete);
      setState(() {
        _isSignedUp = true;
      });
    } on AuthError catch (error) {
      _setError(error);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 2,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Expanded(
            child: Padding(
              padding: EdgeInsets.all(10.0),
              child: Column(
                children: [
                  Visibility(
                    visible: !_isSignedUp,
                    child: Column(children: [
                      TextFormField(
                        enableSuggestions: false,
                        decoration: const InputDecoration(
                          icon: Icon(Icons.email),
                          hintText: 'Email',
                          labelText: 'Email *',
                        ),
                        controller: emailController,
                        keyboardType: TextInputType.emailAddress,
                      ),
                      TextFormField(
                        obscureText: true,
                        enableSuggestions: false,
                        autocorrect: false,
                        decoration: const InputDecoration(
                          icon: Icon(Icons.lock),
                          hintText: 'Password',
                          labelText: 'Password *',
                        ),
                        controller: passwordController,
                      ),
                      const Padding(padding: EdgeInsets.all(10.0)),
                      FlatButton(
                        textColor:
                            Colors.black, // Theme.of(context).primaryColor,
                        color: Colors.amber,
                        onPressed: () => _signUp(context),
                        child: Text(
                          'Create Account',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                      ),
                      FlatButton(
                        height: 5,
                        onPressed: _displaySignIn,
                        child: Text(
                          'Already registered? Sign In',
                          style: Theme.of(context).textTheme.subtitle2,
                        ),
                      ),
                    ]),
                  ),
                  Visibility(
                      visible: _isSignedUp,
                      child: Column(children: [
                        ConfirmSignup(emailController.text.trim(), _setError),
                      ])),
                  ErrorView(_signUpError, _signUpExceptions)
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  void _displaySignIn() {
    widget._displayAccountWidget(AccountStatus.sign_in.index);
  }
}



Enter fullscreen mode Exit fullscreen mode

confirm_signup.dart

To submit the signup confirmation code.


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/screens/next_screen.dart';
import 'package:flutter/material.dart';

class ConfirmSignup extends StatelessWidget {
  final codeController = TextEditingController();
  final String userName;
  final Function setError;

  ConfirmSignup(this.userName, this.setError);

  void _skip_confirm_signup(BuildContext context) {
    _go_to_NextScreen(context);
  }

  void _confirm_signup(BuildContext context) async {
    try {
      SignUpResult res = await Amplify.Auth.confirmSignUp(
          username: this.userName,
          confirmationCode: codeController.text.trim());

      _go_to_NextScreen(context);
    } on AuthError catch (e) {
      setError(e);
    }
  }

  void _go_to_NextScreen(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) {
          return NextScreen();
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // decoration: BoxDecoration(borderRadius: BorderRadius.circular(20)),
      padding: EdgeInsets.all(5),
      child: Column(
        children: [
          TextFormField(
              controller: codeController,
              decoration: const InputDecoration(
                icon: Icon(Icons.confirmation_number),
                hintText: 'The code we sent you',
                labelText: 'Confirmation Code *',
              )),
          FlatButton(
            textColor: Colors.black, // Theme.of(context).primaryColor,
            color: Colors.amber,
            onPressed: () => _confirm_signup(context),
            child: Text(
              'Confirm Sign Up',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ],
      ),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

reset_password.dart

To request a password reset operation.


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/account_screens_enum.dart';
import 'package:auth_for_flutter/widgets/confirm_reset_password.dart';
import 'package:auth_for_flutter/widgets/error_view.dart';
import 'package:flutter/material.dart';

class ResetPasswordView extends StatefulWidget {
  final Function _displayAccountWidget;

  const ResetPasswordView(this._displayAccountWidget);

  @override
  _ResetPasswordViewState createState() => _ResetPasswordViewState();
}

class _ResetPasswordViewState extends State<ResetPasswordView> {
  final emailController = TextEditingController();
  bool _isPasswordReset = false;

  String _signUpError = "";
  List<String> _signUpExceptions = [];

  @override
  void initState() {
    super.initState();
  }

  void _setError(AuthError error) {
    setState(() {
      _signUpError = error.cause;
      _signUpExceptions.clear();
      error.exceptionList.forEach((el) {
        _signUpExceptions.add(el.exception);
      });
    });
  }

  void _resetPassword(BuildContext context) async {
    try {
      ResetPasswordResult res = await Amplify.Auth.resetPassword(
        username: emailController.text.trim(),
      );

      setState(() {
        _isPasswordReset = true;
      });
    } on AuthError catch (e) {
      setState(() {
        _signUpError = e.cause;
        _signUpExceptions.clear();
        e.exceptionList.forEach((el) {
          _signUpExceptions.add(el.exception);
        });
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 2,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Expanded(
            child: Padding(
              padding: EdgeInsets.all(10.0),
              child: Column(
                children: [
                  Visibility(
                    visible: !_isPasswordReset,
                    child: Column(children: [
                      TextFormField(
                        enableSuggestions: false,
                        decoration: const InputDecoration(
                          icon: Icon(Icons.email),
                          hintText: 'Email',
                          labelText: 'Email *',
                        ),
                        controller: emailController,
                        keyboardType: TextInputType.emailAddress,
                      ),
                      const Padding(padding: EdgeInsets.all(10.0)),
                      FlatButton(
                        textColor:
                            Colors.black, // Theme.of(context).primaryColor,
                        color: Colors.amber,
                        onPressed: () => _resetPassword(context),
                        child: Text(
                          'Reset Password',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                      ),
                      FlatButton(
                        height: 5,
                        onPressed: _displayCreateAccount,
                        child: Text(
                          'Create Account',
                          style: Theme.of(context).textTheme.subtitle2,
                        ),
                      ),
                    ]),
                  ),
                  Visibility(
                      visible: _isPasswordReset,
                      child: Column(children: [
                        ConfirmResetPassword(
                            emailController.text.trim(), _setError),
                      ])),
                  ErrorView(_signUpError, _signUpExceptions)
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  void _displayCreateAccount() {
    widget._displayAccountWidget(AccountStatus.sign_up.index);
  }
}


Enter fullscreen mode Exit fullscreen mode

confirm_reset_password.dart

To submit the confirmation code and the new password.


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/screens/next_screen.dart';
import 'package:flutter/material.dart';

class ConfirmResetPassword extends StatelessWidget {
  final codeController = TextEditingController();
  final emailController = TextEditingController();
  final passwordController = TextEditingController();
  final String userName;
  final Function setError;

  ConfirmResetPassword(this.userName, this.setError);

  void _confirm_password_reset(BuildContext context) async {
    try {
      await Amplify.Auth.confirmPassword(
          username: this.userName,
          newPassword: passwordController.text.trim(),
          confirmationCode: codeController.text.trim());
      _go_to_NextScreen(context);
    } on AuthError catch (e) {
      setError(e);
    }
  }

  void _go_to_NextScreen(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) {
          return NextScreen();
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // decoration: BoxDecoration(borderRadius: BorderRadius.circular(20)),
      padding: EdgeInsets.all(5),
      child: Column(
        children: [
          TextFormField(
            enableSuggestions: false,
            decoration: const InputDecoration(
              icon: Icon(Icons.email),
              hintText: 'Email',
              labelText: 'Email *',
            ),
            controller: emailController,
            keyboardType: TextInputType.emailAddress,
          ),
          TextFormField(
            obscureText: true,
            enableSuggestions: false,
            autocorrect: false,
            decoration: const InputDecoration(
              icon: Icon(Icons.lock),
              hintText: 'New Password',
              labelText: 'New Password *',
            ),
            controller: passwordController,
          ),
          TextFormField(
              controller: codeController,
              decoration: const InputDecoration(
                icon: Icon(Icons.confirmation_number),
                hintText: 'The code we sent you',
                labelText: 'Confirmation Code *',
              )),
          FlatButton(
            textColor: Colors.black, // Theme.of(context).primaryColor,
            color: Colors.amber,
            onPressed: () => _confirm_password_reset(context),
            child: Text(
              'Reset Password & Sign In',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ],
      ),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

sign_in.dart

The sign-in operation


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/account_screens_enum.dart';
import 'package:auth_for_flutter/screens/next_screen.dart';
import 'package:auth_for_flutter/widgets/error_view.dart';
import 'package:flutter/material.dart';

class SignInView extends StatefulWidget {
  final Function _displayAccountWidget;

  const SignInView(this._displayAccountWidget);

  @override
  _SignInViewState createState() => _SignInViewState();
}

class _SignInViewState extends State<SignInView> {
  final emailController = TextEditingController();
  final passwordController = TextEditingController();
  String _signUpError = "";
  List<String> _signUpExceptions = [];

  @override
  void initState() {
    super.initState();
  }

  void _setError(AuthError error) {
    setState(() {
      _signUpError = error.cause;
      _signUpExceptions.clear();
      error.exceptionList.forEach((el) {
        _signUpExceptions.add(el.exception);
      });
    });
  }

  void _signIn() async {
    // Sign out before in case a user is already signed in
    // If a user is already signed in - Amplify.Auth.signIn will throw an exception
    try {
      await Amplify.Auth.signOut();
    } on AuthError catch (e) {
      print(e);
    }

    try {
      SignInResult res = await Amplify.Auth.signIn(
          username: emailController.text.trim(),
          password: passwordController.text.trim());
      _go_to_NextScreen(context);
    } on AuthError catch (e) {
      setState(() {
        _signUpError = e.cause;
        _signUpExceptions.clear();
        e.exceptionList.forEach((el) {
          _signUpExceptions.add(el.exception);
        });
      });
    }
  }

  void _go_to_NextScreen(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) {
          return NextScreen();
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 2,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Expanded(
            // wrap your Column in Expanded
            child: Padding(
              padding: EdgeInsets.all(10.0),
              child: Column(
                children: [
                  TextFormField(
                    controller: emailController,
                    decoration: const InputDecoration(
                      icon: Icon(Icons.email),
                      hintText: 'Enter your email',
                      labelText: 'Email *',
                    ),
                  ),
                  TextFormField(
                    obscureText: true,
                    controller: passwordController,
                    decoration: const InputDecoration(
                      icon: Icon(Icons.lock),
                      hintText: 'Enter your password',
                      labelText: 'Password *',
                    ),
                  ),
                  const Padding(padding: EdgeInsets.all(10.0)),
                  FlatButton(
                    textColor: Colors.black, // Theme.of(context).primaryColor,
                    color: Colors.amber,
                    onPressed: _signIn,
                    child: const Text(
                      'Sign In',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      FlatButton(
                        height: 5,
                        onPressed: _displayCreateAccount,
                        child: Text(
                          'Create Account',
                          style: Theme.of(context).textTheme.subtitle2,
                        ),
                      ),
                      FlatButton(
                        height: 5,
                        onPressed: _displayResetPassword,
                        child: Text(
                          'Reset Password',
                          style: Theme.of(context).textTheme.subtitle2,
                        ),
                      ),
                    ],
                  ),
                  ErrorView(_signUpError, _signUpExceptions)
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  void _displayCreateAccount() {
    widget._displayAccountWidget(AccountStatus.sign_up.index);
  }

  void _displayResetPassword() {
    widget._displayAccountWidget(AccountStatus.reset_password.index);
  }
}


Enter fullscreen mode Exit fullscreen mode

error_view.dart

Display the error messages.


import 'package:flutter/material.dart';

class ErrorView extends StatelessWidget {
  final String error;
  final List<String> exceptions;

  ErrorView(this.error, this.exceptions);

  @override
  Widget build(BuildContext context) {
    // We do not recognize your username and/or password. Please try again.
    if (error.isNotEmpty || exceptions.length > 0) {
      return Column(children: <Widget>[
        Text('Error: $error',
            textAlign: TextAlign.center,
            overflow: TextOverflow.visible,
            style: TextStyle(
              fontWeight: FontWeight.bold,
              color: Theme.of(context).errorColor,
            )),
        if (exceptions.length > 0) ...[_showExceptions(context)]
      ]);
    } else {
      return Container();
    }
  }

  _showExceptions(context) {
    return Column(
        children: exceptions
            .map((item) => new Text(item + " ",
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  color: Theme.of(context).errorColor,
                )))
            .toList());
  }
}


Enter fullscreen mode Exit fullscreen mode

We will have three screens in the App. Create the screens below in the (lib\screens) folder

loading_screen.dart


import 'package:flutter/material.dart';

class LoadingScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('BatMan App')),
      body: Container(
        color: Color(0xff90CCE6),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                color: Color(0xffE1E5E4),
                height: 200,
                child: Image.asset(
                  'assets/images/applogo.png',
                  fit: BoxFit.cover,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Center(
                  child: CircularProgressIndicator(),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

main_screen.dart


import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:auth_for_flutter/account_screens_enum.dart';
import 'package:auth_for_flutter/screens/next_screen.dart';
import 'package:auth_for_flutter/widgets/reset_password.dart';
import 'package:auth_for_flutter/widgets/sign_in.dart';
import 'package:auth_for_flutter/widgets/sign_up.dart';
import 'package:flutter/material.dart';

class MainScreen extends StatefulWidget {
  @override
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  var _accountWidget;

  @override
  initState() {
    super.initState();
    _fetchSession();
  }

  void _fetchSession() async {
    // Sign out before in case a user is already signed in
    try {
      await Amplify.Auth.signOut();
    } on AuthError catch (e) {
      print(e);
    }
    _accountWidget = AccountStatus.sign_in.index;
    _displayAccountWidget(_accountWidget);
  }

  void _go_to_NextScreen(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) {
          return NextScreen();
        },
      ),
    );
  }

  void _displayAccountWidget(int accountStatus) {
    setState(() {
      _accountWidget = AccountStatus.values[accountStatus];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('BatMan App'),
      ),
      body: Container(
        color: Color(0xffE1E5E4),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                color: Color(0xffE1E5E4),
                height: 200,
                child: Image.asset(
                  'assets/images/applogo.png',
                  fit: BoxFit.cover,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(children: [
                  Visibility(
                    visible: _accountWidget == AccountStatus.sign_in,
                    child: SignInView(_displayAccountWidget),
                  ),
                  Visibility(
                    visible: _accountWidget == AccountStatus.sign_up,
                    child: SignUpView(_displayAccountWidget),
                  ),
                  Visibility(
                    visible: _accountWidget == AccountStatus.reset_password,
                    child: ResetPasswordView(_displayAccountWidget),
                  ),
                  Visibility(
                    visible: _accountWidget == AccountStatus.main_screen,
                    child: NextScreen(),
                  ),
                ]),
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

next_screen.dart


import 'package:auth_for_flutter/screens/main_screen.dart';
import 'package:flutter/material.dart';

class NextScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('BatMan App')),
      body: Container(
        color: Color(0xffE1E5E4),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                color: Color(0xffE1E5E4),
                height: 200,
                child: Image.asset(
                  'assets/images/applogo.png',
                  fit: BoxFit.cover,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(20.0),
                child: Center(
                  child: Text(
                    'I\'m BATMAN',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(20.0),
                child: Center(
                  child: RaisedButton(
                    color: Colors.lightBlue,
                    onPressed: () => _signOut(context),
                    child: Text(
                      'Sign Out',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: 20,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _signOut(BuildContext context) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) {
          return MainScreen();
        },
      ),
    );
  }
}



Enter fullscreen mode Exit fullscreen mode

Run the App

Check the code here

Follow me on Twitter for more tips about #coding, #learning, #technology...etc.

Check my Apps on Google Play

Cover image Obi Onyeador on Unsplash

💖 💪 🙅 🚩
offlineprogrammer
Offline Programmer

Posted on January 14, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

How I use Amplify Auth with Flutter
flutter How I use Amplify Auth with Flutter

January 14, 2021