import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Realtime Todo List',
home: const TodoScreen(),
);
}
}
class TodoScreen extends StatefulWidget {
const TodoScreen({super.key});
@override
State<TodoScreen> createState() => _TodoScreenState();
}
class _TodoScreenState extends State<TodoScreen> {
final DatabaseReference _todoRef = FirebaseDatabase.instance.ref('todos');
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Realtime Todo List')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: const InputDecoration(
labelText: 'New Task',
),
),
),
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
final text = _controller.text.trim();
if (text.isNotEmpty) {
_todoRef.push().set({'task': text});
_controller.clear();
}
},
),
],
),
),
Expanded(
child: StreamBuilder<DatabaseEvent>(
stream: _todoRef.onValue,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data!.snapshot.value != null) {
final data = Map<String, dynamic>.from(snapshot.data!.snapshot.value as Map);
final tasks = data.entries.toList();
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
final key = tasks[index].key;
final task = tasks[index].value['task'] as String;
return ListTile(
title: Text(task),
onTap: () {
_todoRef.child(key).remove();
},
);
},
);
} else if (snapshot.hasError) {
return Center(child: Text('Error loading tasks'));
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
),
],
),
);
}
}
This app connects to Firebase Realtime Database and listens to the 'todos' node using onValue stream. When data changes, the UI updates instantly showing the current list of tasks.
Users can add new tasks by typing in the TextField and pressing the '+' button. This pushes a new child with the task text to the database.
Tapping a task removes it from the database, which also updates the UI in real-time.
This shows how easy it is to build a live-updating app with Firebase Realtime Database and Flutter.