snehaa1989Learn how to create a complete Android application using Flutter and Firebase from scratch ...
Learn how to create a complete Android application using Flutter and Firebase from scratch
Flutter has revolutionized mobile app development by allowing developers to create beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. When combined with Firebase, Google's mobile and web application development platform, you get a powerful stack that handles everything from authentication to real-time databases.
In this tutorial, we'll build a simple Task Management App that demonstrates:
Before we start, make sure you have:
If you haven't installed Flutter yet:
# Download Flutter SDK from https://flutter.dev/docs/get-started/install
# Extract and add to PATH
export PATH="$PATH:/path/to/flutter/bin"
# Verify installation
flutter doctor
Run this command to ensure everything is working:
flutter doctor -v
You should see green checkmarks for:
Let's create our Flutter project:
# Create a new Flutter project
flutter create task_manager_app
cd task_manager_app
# Open in VS Code (optional)
code .
task_manager_app/
โโโ android/ # Android-specific code
โโโ ios/ # iOS-specific code
โโโ lib/ # Main Dart code
โ โโโ main.dart # Entry point
โ โโโ screens/ # App screens
โโโ pubspec.yaml # Dependencies
โโโ test/ # Test files
task-manager-app
android/app/build.gradle (usually com.example.task_manager_app)google-services.json
android/app/ directoryIn your Firebase project, enable:
Update your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
firebase_core: ^2.15.0
firebase_auth: ^4.7.0
cloud_firestore: ^4.8.0
firebase_ui_auth: ^1.6.0
Run flutter pub get to install dependencies.
Add these lines to android/app/build.gradle:
apply plugin: 'com.google.gms.google-services'
android {
// ...
defaultConfig {
// ...
minSdkVersion 19
}
}
Add to android/build.gradle:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
Let's create a simple task management interface.
Replace lib/main.dart:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'screens/auth_screen.dart';
import 'screens/home_screen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Task Manager',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: AuthWrapper(),
);
}
}
class AuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser;
return user != null ? HomeScreen() : AuthScreen();
}
}
Create lib/screens/auth_screen.dart:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class AuthScreen extends StatefulWidget {
@override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
bool _isLogin = true;
bool _isLoading = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_isLogin ? 'Login' : 'Sign Up'),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _emailController,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
),
SizedBox(height: 16),
TextField(
controller: _passwordController,
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(),
),
obscureText: true,
),
SizedBox(height: 24),
_isLoading
? CircularProgressIndicator()
: ElevatedButton(
onPressed: _authenticate,
child: Text(_isLogin ? 'Login' : 'Sign Up'),
style: ElevatedButton.styleFrom(
minimumSize: Size(double.infinity, 50),
),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Don\'t have an account? Sign up'
: 'Already have an account? Login'),
),
],
),
),
);
}
Future<void> _authenticate() async {
setState(() => _isLoading = true);
try {
if (_isLogin) {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text.trim(),
password: _passwordController.text,
);
} else {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text.trim(),
password: _passwordController.text,
);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${e.message}')),
);
} finally {
setState(() => _isLoading = false);
}
}
}
Create lib/screens/home_screen.dart:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final _taskController = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
@override
Widget build(BuildContext context) {
final user = _auth.currentUser;
return Scaffold(
appBar: AppBar(
title: Text('Task Manager'),
actions: [
IconButton(
icon: Icon(Icons.logout),
onPressed: _logout,
),
],
),
body: Column(
children: [
Padding(
padding: EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _taskController,
decoration: InputDecoration(
labelText: 'Add a new task',
border: OutlineInputBorder(),
),
),
),
SizedBox(width: 8),
IconButton(
icon: Icon(Icons.add),
onPressed: _addTask,
style: IconButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
),
],
),
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('tasks')
.where('userId', isEqualTo: user?.uid)
.orderBy('createdAt', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
return Center(child: Text('No tasks yet. Add one!'));
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.data!.docs[index];
final task = doc.data() as Map<String, dynamic>;
return Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
title: Text(task['title']),
subtitle: Text(
'Created: ${task['createdAt'].toDate().toString().substring(0, 19)}',
),
trailing: IconButton(
icon: Icon(Icons.delete, color: Colors.red),
onPressed: () => _deleteTask(doc.id),
),
leading: Checkbox(
value: task['completed'] ?? false,
onChanged: (value) => _toggleTask(doc.id, value!),
),
),
);
},
);
},
),
),
],
),
);
}
Future<void> _addTask() async {
if (_taskController.text.trim().isEmpty) return;
final user = _auth.currentUser;
if (user == null) return;
try {
await _firestore.collection('tasks').add({
'title': _taskController.text.trim(),
'completed': false,
'userId': user.uid,
'createdAt': Timestamp.now(),
});
_taskController.clear();
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error adding task: $e')),
);
}
}
Future<void> _deleteTask(String taskId) async {
try {
await _firestore.collection('tasks').doc(taskId).delete();
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error deleting task: $e')),
);
}
}
Future<void> _toggleTask(String taskId, bool completed) async {
try {
await _firestore.collection('tasks').doc(taskId).update({
'completed': completed,
});
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error updating task: $e')),
);
}
}
Future<void> _logout() async {
await _auth.signOut();
}
}
Our authentication system is already implemented! Here's what we've done:
Firestore is a flexible, scalable NoSQL cloud database. Here's how we're using it:
tasks/
[taskId]: {
title: "Complete Flutter tutorial",
completed: false,
userId: "user-uid",
createdAt: timestamp
}
# Check available devices
flutter devices
# Run on specific device
flutter run -d <device-id>
flutter devices to verify connectionflutter run
Authentication Flow
Task Management
Real-time Updates
const constructorsCongratulations! You've built a complete Flutter app with Firebase integration. Here are some ways to enhance your app:
Add More Features
Improve UI/UX
Advanced Firebase
Deployment
flutter build apk --release
Building mobile apps with Flutter and Firebase offers an incredible development experience. You get:
The combination of Flutter's expressive UI framework and Firebase's powerful backend services makes it possible to build production-quality applications quickly and efficiently.
Remember, this is just the beginning. The Flutter and Firebase ecosystems are constantly evolving, with new features and improvements being added regularly. Keep learning, experimenting, and building amazing apps!