Develop an Android App with Flutter/Amplify
Published: 2023-04-13 16:40:53



**What is Flutter?**
Flutter is an open source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase. The same codebase can be run on Mobile, web and Desktop. 

**What is Amplify?**
Amplify is a service from AWS, like Firebase, that provides easy ways to create some of the must-have things of any app out there, such as:
API 
Auth
DataStore 

Amplify lets you interact with the app being built, using CLI locally and from AWS console on the server side. Both sides you can see the same app if you do amplify push and amplify pull as needed. 

Here's the source code for this demo: https://github.com/manumaan/flutter_demo

**Setup the Developer Toolchain for Android App:**
1. Install flutter from `flutter.dev `according to your operating system. Flutter SDK will be unzipped to a location. Add the path to flutter/bin to the PATH variable of the OS. 

2. From `https://developer.android.com/studio` download and install Android Studio. 

3. Setup your android device. Enable Developer Options (tap Build Number 7 times) and then enable USB Debugging from Developer Options. 

On Windows Install Google USB Drivers - `https://developer.android.com/studio/run/win-usb`

Using a USB cable, plug your phone into your computer. If prompted on your device, authorize your computer to access your device.
In the terminal, run the flutter devices command to verify that Flutter recognizes your connected Android device. 

4. Run `flutter doctor --android-licenses `to agree to licenses. 

5. On MacOS, install Xcode additionally from `https://developer.apple.com/xcode/`

6. Run `flutter doctor -v` to check if there are any issues with your setup. 

**Install & Configure Amplify CLI**
PreRequisite: have Node.js and npm installed on your machine.
Below commands will do this using nvm. 
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
nvm install node
nvm install-latest-npm
```

Run below command to install amplify CLI
```
curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL
```

To configure amplify:
`amplify configure `

This will ask for your aws region, IAM user, and for Access Key pair for the user using whom the amplify will run and connect to the AWS. Use a user who has `AdministratorAccess-Amplify` policy assigned to. 

**Create your first app**

Run `flutter create <your_app_name>` to create folder structure and scaffolding for your app. 

![flutter create](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/quxfvj3mvi3jx28og15x.png)

In the root folder, find pubspec.yaml, this folder contains all the libraries used by your app. Add amplify to this.Final file looks like this:

```
environment:
  sdk: ">=2.15.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  amplify_flutter: ^0.6.0
  amplify_auth_cognito: ^0.6.0
```

run `flutter pub get` to pull all the libraries we added.

**Folder Structure** 
Each platform supported has its own folder, like Android, Ios, Linux, MacOS etc. The Android and iOS folders exist to actually build an app on those respective platforms with the Dart files running on them. They also help you add permissions and platform-specific functionality to your project. lib folder contains the actual codebase that we will edit. main.dart inside lib is the code that we will edit. 

**Run your app**
run `flutter run `to run your app on an available device. It will display the available devices. If your phone is not connected via USB Cable, it will display default browser and the desktop OS. Connect your phone with USB cable and accept prompt for USB Debugging. 

Now running `flutter run` should run your app on the device.The beginner project contains a screen that shows the title, and a + button that when you press, increments a counter on the screen. 

![flutter run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jrsqud2r4uml9duf60n.png)

One cool feature of flutter is stateful hot reload. This means you can reflect code-changes on a running app without delay. To test this you can change the below line in main.dart:

`primarySwatch: Colors.green`

to some other color and press R to see the code change take effect immediately.


![Hot Reload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yurzazjsz85xvqvw78g.png)



Also note that while the app is running on the device you can see terminal output where you ran the flutter run command. Note: You can add print() statements to your code if you find yourself in a fix and dont know what you goofed up. Make sure to remove them before you build your final APK.

**Configure Amplify for your project**
Each of the backend functionalities are added via `amplify add` command. In the next section we will add a signup and login functionality by using amplify. 

First run `amplify init` to initialize Amplify for your project. This command has to be run from the project folder root. This command creates an amplify folder inside your project as well as lib/amplifyconfiguration.dart 

![amplify init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6847ltgrabd6lzoex7k.png)



Now run 
`flutter pub add amplify_flutter` to add the libraries. 

Import both amplify library and the configuration.dart into your main.dart. In below code replace amplify_demo with your project name when you did `flutter create`


```
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_demo/amplifyconfiguration.dart';
```

Add below code to your main.dart, this function will configure amplify when your app starts. 

```
Future<void> _configureAmplify() async {
  try{
   await Amplify.configure(amplifyconfig);
  }
  catch(e) {
    print('An Error occured while initializing Amplify : $e');
  }
```

Now to ensure it gets called, add it to your main() method.

```
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _configureAmplify(); 
  runApp(const MyApp());
}
```
Make sure that, minSdkVersion in /android/app/build.gradle must be 24 to support Amplify.

**Add Auth to your app with Amplify**

Run the command `amplify add auth` from your project root directory. This command will ask for options, and select all default options. This will add aws cognito to authenticate the user, and user will be able to signup using an email.This is the default basic option, and other advanced auth options are also available. We will be seeing the default option in this article. 

![amplifyauth](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7azm8n2ba1n08v28v8e.png)



Once your command is completed, run `flutter pub add amplify_auth_cognito` to add the libraries to the app.

Import auth libraries in your main.dart as below
```
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
```

Since we have added stuff for amplify to configure, we need to edit the configureAmplify() function as below:

```
Future<void> _configureAmplify() async {
  try{
   final amplifyAuthCognito = AmplifyAuthCognito();
   await Amplify.addPlugins([amplifyAuthCognito]);
   await Amplify.configure(amplifyconfig);
  }
  catch(e) {
    print('An Error occured while initializing Amplify : $e');
  }
}
```

Now run `amplify push` to push the changes upto AWS Cloud. 

Lets go ahead and add the UI for the signup and sign-in processes. Now you may be scratching your head and thinking about the amount of UI development involved but Amplify will help you out here. 

[Amplify UI ](https://ui.docs.amplify.aws/) Is a set of themable, accessible UI components that you can use in React, Vue JS, Flutter and other languages of choice. We are going to use a ready-made component for our purpose. We will be using the Authenticator component. Disclaimer: As of writing this, Authenticator is the only component for flutter,but react etc have many more components available in Amplify UI.

Add the library to project:
`flutter pub add amplify_authenticator`

We can wrap the MaterialApp constructor with the Authenticator to get all the requisite UI elements.

Import the library: 

```
import 'package:amplify_authenticator/amplify_authenticator.dart';
```

Update your code to look like this: 
```
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
  return Authenticator(
    child: MaterialApp(
      title: 'My App',
      builder: Authenticator.builder(),
      home: const MyHomePage(title: 'My App'),
    )
  );
  }
}
```
You also need to update the code that creates the homepage widget like below, to add the sign out button. 

```
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), 
            SignOutButton(),
          ],
        ),
      ),

    );
  }
```

Now we can run the app again and this time, you should get a sign-up screen, and you should be able to sign-up and sign-in.
Don't be alarmed if you see an "error" like this on your terminal: 

```
W/AWSMobileClient( 9138): com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Unauthenticated access is not supported for this identity pool. ( 
```

It is a warning, and all it means that the user using the App is not signed in and your federated cognito pool does not allow unauthorized login. 

Give a username, password, email and signup. This will send a verification email to the given email from the account verificationemail.com There is a good chance your gmail puts it in the junk folder. Verify your signup and you will be able to sign-in. 


![AppScreenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3zbu731rn8u8t8tkw3k.png)