Flutter AWS Amplify
Build scalable Flutter apps with AWS cloud services
☁️ What is AWS Amplify?
AWS Amplify is a complete development platform for building scalable mobile and web apps. It provides authentication, APIs, storage, analytics, and more, all powered by AWS cloud infrastructure for enterprise-grade Flutter applications.
// Initialize Amplify
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
await Amplify.addPlugins([
AmplifyAuthCognito(),
]);
await Amplify.configure(amplifyconfig);
Key Amplify Features
Authentication
Secure user authentication with Amazon Cognito. Supports email/password, social logins, multi-factor authentication, and user management with enterprise-level security and compliance features.
await Amplify.Auth.signUp(
username: email,
password: password,
);
API (GraphQL/REST)
Create scalable APIs with AWS AppSync and API Gateway. Build GraphQL or REST APIs that automatically scale, with real-time capabilities and offline data synchronization built-in.
final request = GraphQLRequest(
document: listTodos,
);
final response = await Amplify.API.query(request: request);
Storage
Store files in Amazon S3 with built-in CDN. Upload images, videos, and documents with automatic compression, resizing, and global content delivery for fast access worldwide.
await Amplify.Storage.uploadFile(
localFile: file,
key: 'uploads/photo.jpg',
);
Analytics
Track user behavior with Amazon Pinpoint. Monitor app usage, user engagement, and custom events to understand how users interact with your app and improve user experience.
await Amplify.Analytics.recordEvent(
event: AnalyticsEvent('ButtonClicked'),
);
🔹 Setting Up Amplify
Install Amplify CLI and configure your Flutter project:
# Install Amplify CLI globally
npm install -g @aws-amplify/cli
# Configure Amplify with your AWS account
amplify configure
# Initialize Amplify in your Flutter project
amplify init
# Add authentication
amplify add auth
# Add API
amplify add api
# Push changes to AWS
amplify push
# pubspec.yaml
dependencies:
flutter:
sdk: flutter
amplify_flutter: ^1.5.0
amplify_auth_cognito: ^1.5.0
amplify_api: ^1.5.0
amplify_storage_s3: ^1.5.0
Setup steps:
1. Install Amplify CLI
2. Configure AWS credentials
3. Initialize Amplify in project
4. Add required services
5. Deploy to AWS cloud
🔹 Configuring Amplify in Flutter
Initialize Amplify in your Flutter app:
// main.dart
import 'package:flutter/material.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_storage_s3/amplify_storage_s3.dart';
import 'amplifyconfiguration.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _configureAmplify();
runApp(MyApp());
}
Future<void> _configureAmplify() async {
try {
// Add plugins
await Amplify.addPlugins([
AmplifyAuthCognito(),
AmplifyAPI(),
AmplifyStorageS3(),
]);
// Configure Amplify
await Amplify.configure(amplifyconfig);
print('Amplify configured successfully');
} catch (e) {
print('Error configuring Amplify: $e');
}
}
What this does:
✓ Initializes Amplify before app starts
✓ Adds authentication, API, and storage
✓ Connects to AWS services
🔹 Authentication with Cognito
Implement user sign up and sign in:
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/material.dart';
class AuthService {
// Sign Up
Future<bool> signUp(String email, String password) async {
try {
final result = await Amplify.Auth.signUp(
username: email,
password: password,
options: SignUpOptions(
userAttributes: {
AuthUserAttributeKey.email: email,
},
),
);
return result.isSignUpComplete;
} on AuthException catch (e) {
print('Sign up error: ${e.message}');
return false;
}
}
// Confirm Sign Up
Future<bool> confirmSignUp(String email, String code) async {
try {
final result = await Amplify.Auth.confirmSignUp(
username: email,
confirmationCode: code,
);
return result.isSignUpComplete;
} on AuthException catch (e) {
print('Confirmation error: ${e.message}');
return false;
}
}
// Sign In
Future<bool> signIn(String email, String password) async {
try {
final result = await Amplify.Auth.signIn(
username: email,
password: password,
);
return result.isSignedIn;
} on AuthException catch (e) {
print('Sign in error: ${e.message}');
return false;
}
}
// Sign Out
Future<void> signOut() async {
try {
await Amplify.Auth.signOut();
} on AuthException catch (e) {
print('Sign out error: ${e.message}');
}
}
// Get Current User
Future<AuthUser?> getCurrentUser() async {
try {
final user = await Amplify.Auth.getCurrentUser();
return user;
} on AuthException catch (e) {
print('Get user error: ${e.message}');
return null;
}
}
}
// Usage in a widget
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
final authService = AuthService();
Future<void> handleSignIn() async {
final success = await authService.signIn(
emailController.text,
passwordController.text,
);
if (success) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Sign in failed')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
decoration: InputDecoration(labelText: 'Email'),
),
SizedBox(height: 16),
TextField(
controller: passwordController,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
SizedBox(height: 24),
ElevatedButton(
onPressed: handleSignIn,
child: Text('Sign In'),
),
],
),
),
);
}
}
🔹 GraphQL API Operations
Query and mutate data with GraphQL:
import 'package:amplify_flutter/amplify_flutter.dart';
// Query - Fetch all todos
Future<List<Todo>> fetchTodos() async {
try {
const graphQLDocument = '''
query ListTodos {
listTodos {
items {
id
name
description
completed
}
}
}
''';
final request = GraphQLRequest<String>(
document: graphQLDocument,
);
final response = await Amplify.API.query(request: request).response;
final data = response.data;
// Parse and return todos
return parseTodos(data);
} on ApiException catch (e) {
print('Query error: $e');
return [];
}
}
// Mutation - Create a new todo
Future<Todo?> createTodo(String name, String description) async {
try {
const graphQLDocument = '''
mutation CreateTodo(\$name: String!, \$description: String!) {
createTodo(input: {name: \$name, description: \$description}) {
id
name
description
completed
}
}
''';
final request = GraphQLRequest<String>(
document: graphQLDocument,
variables: {
'name': name,
'description': description,
},
);
final response = await Amplify.API.mutate(request: request).response;
// Parse and return created todo
return parseTodo(response.data);
} on ApiException catch (e) {
print('Mutation error: $e');
return null;
}
}
// Mutation - Update todo
Future<bool> updateTodo(String id, bool completed) async {
try {
const graphQLDocument = '''
mutation UpdateTodo(\$id: ID!, \$completed: Boolean!) {
updateTodo(input: {id: \$id, completed: \$completed}) {
id
completed
}
}
''';
final request = GraphQLRequest<String>(
document: graphQLDocument,
variables: {
'id': id,
'completed': completed,
},
);
await Amplify.API.mutate(request: request).response;
return true;
} on ApiException catch (e) {
print('Update error: $e');
return false;
}
}
🔹 File Storage with S3
Upload and download files to Amazon S3:
import 'dart:io';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:image_picker/image_picker.dart';
class StorageService {
// Upload file
Future<String?> uploadFile(File file, String key) async {
try {
final result = await Amplify.Storage.uploadFile(
localFile: AWSFile.fromPath(file.path),
key: key,
options: StorageUploadFileOptions(
accessLevel: StorageAccessLevel.guest,
),
).result;
print('Upload successful: ${result.uploadedItem.key}');
return result.uploadedItem.key;
} on StorageException catch (e) {
print('Upload error: $e');
return null;
}
}
// Download file
Future<File?> downloadFile(String key, String localPath) async {
try {
final result = await Amplify.Storage.downloadFile(
key: key,
localFile: AWSFile.fromPath(localPath),
).result;
print('Download successful: ${result.localFile.path}');
return File(result.localFile.path);
} on StorageException catch (e) {
print('Download error: $e');
return null;
}
}
// Get file URL
Future<String?> getFileUrl(String key) async {
try {
final result = await Amplify.Storage.getUrl(
key: key,
options: StorageGetUrlOptions(
accessLevel: StorageAccessLevel.guest,
expires: 3600, // URL valid for 1 hour
),
).result;
return result.url.toString();
} on StorageException catch (e) {
print('Get URL error: $e');
return null;
}
}
// List files
Future<List<String>> listFiles() async {
try {
final result = await Amplify.Storage.list().result;
return result.items.map((item) => item.key).toList();
} on StorageException catch (e) {
print('List error: $e');
return [];
}
}
// Delete file
Future<bool> deleteFile(String key) async {
try {
await Amplify.Storage.remove(key: key).result;
return true;
} on StorageException catch (e) {
print('Delete error: $e');
return false;
}
}
}
// Usage example
class ImageUploadScreen extends StatelessWidget {
final storageService = StorageService();
Future<void> pickAndUploadImage() async {
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
final file = File(image.path);
final key = 'images/${DateTime.now().millisecondsSinceEpoch}.jpg';
final uploadedKey = await storageService.uploadFile(file, key);
if (uploadedKey != null) {
final url = await storageService.getFileUrl(uploadedKey);
print('Image URL: $url');
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Upload Image')),
body: Center(
child: ElevatedButton(
onPressed: pickAndUploadImage,
child: Text('Pick and Upload Image'),
),
),
);
}
}