Flutter, Google’s UI toolkit, makes it easier to build natively compiled applications for mobile, web, and desktop from a single codebase. When developing real-time applications, a real-time database like Firebase Realtime Database can be an excellent choice. This guide will walk you through how to use Firebase Realtime Database in your Flutter applications.
What is Firebase Realtime Database?
Firebase Realtime Database is a cloud-hosted, NoSQL database that lets you store and synchronize data between your users in real-time. The data is stored as one large JSON tree, and clients connected to the database receive automatic updates with the newest data.
Why Use Firebase Realtime Database with Flutter?
- Real-time Data: Offers immediate data synchronization across all connected devices.
- Scalability: Automatically scales to meet your app’s needs.
- Offline Capabilities: Caches data locally for offline access.
- Ease of Use: Simple API for reading and writing data.
How to Implement Firebase Realtime Database in Flutter
To implement Firebase Realtime Database in Flutter, follow these steps:
Step 1: Set up Firebase Project
- Go to the Firebase Console and create a new project.
- Follow the setup steps, and enable Realtime Database in your Firebase project.
Step 2: Add Firebase to Your Flutter App
- Install the Firebase CLI:
- Create a Flutter Project:
- Add Firebase Core and Realtime Database dependencies to
pubspec.yaml: - Run
flutter pub getto install the dependencies.
npm install -g firebase-tools
firebase login
flutter create flutter_realtime_db_app
cd flutter_realtime_db_app
dependencies:
flutter:
sdk: flutter
firebase_core: ^2.15.0
firebase_database: ^10.2.0
Step 3: Configure Firebase in Your Flutter App
- Initialize Firebase in your Flutter app:
- Ensure that you have generated the
firebase_options.dartfile by running:
In your main.dart file, add the following code:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Realtime DB Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Firebase Realtime DB Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text('Firebase initialized!'),
),
);
}
}
flutterfire configure
Step 4: Write Data to Firebase Realtime Database
- Import necessary packages:
- Write data to the database:
- Integrate the write function in your UI:
import 'package:firebase_database/firebase_database.dart';
final databaseReference = FirebaseDatabase.instance.ref();
void createData() {
databaseReference.child("users").child("123").set({
'name': 'John Doe',
'email': 'john.doe@example.com'
});
}
ElevatedButton(
onPressed: () {
createData();
},
child: Text('Create Data'),
)
Step 5: Read Data from Firebase Realtime Database
- Read data from the database:
- Integrate the read function in your UI:
void readData() {
databaseReference.child("users/123").get().then((snapshot) {
if (snapshot.exists) {
print('Data: ${snapshot.value}');
} else {
print('No data available.');
}
}).catchError((error) {
print('Error: $error');
});
}
ElevatedButton(
onPressed: () {
readData();
},
child: Text('Read Data'),
)
Step 6: Update Data in Firebase Realtime Database
- Update data in the database:
- Integrate the update function in your UI:
void updateData() {
databaseReference.child("users/123").update({
'email': 'john.newemail@example.com',
'name': 'John A. Doe',
});
}
ElevatedButton(
onPressed: () {
updateData();
},
child: Text('Update Data'),
)
Step 7: Delete Data in Firebase Realtime Database
- Delete data from the database:
- Integrate the delete function in your UI:
void deleteData() {
databaseReference.child("users/123").remove().then((_) {
print('Data deleted successfully');
}).catchError((error) {
print('Error deleting data: $error');
});
}
ElevatedButton(
onPressed: () {
deleteData();
},
child: Text('Delete Data'),
)
Step 8: Real-time Data Listening
- Listen for real-time data changes:
- Call the listen function in your
initStateor relevant places:
void listenForChanges() {
databaseReference.child("users").onValue.listen((event) {
if (event.snapshot.exists) {
print('Data updated: ${event.snapshot.value}');
} else {
print('No data available.');
}
});
}
@override
void initState() {
super.initState();
listenForChanges();
}
Complete Example
Here’s a complete example integrating all the above functionalities in a single Flutter widget:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase Realtime DB Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Firebase Realtime DB Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final databaseReference = FirebaseDatabase.instance.ref();
String data = 'No data';
@override
void initState() {
super.initState();
listenForChanges();
}
void createData() {
databaseReference.child("users").child("123").set({
'name': 'John Doe',
'email': 'john.doe@example.com'
});
}
void readData() {
databaseReference.child("users/123").get().then((snapshot) {
if (snapshot.exists) {
setState(() {
data = 'Data: ${snapshot.value}';
});
print('Data: ${snapshot.value}');
} else {
print('No data available.');
}
}).catchError((error) {
print('Error: $error');
});
}
void updateData() {
databaseReference.child("users/123").update({
'email': 'john.newemail@example.com',
'name': 'John A. Doe',
});
}
void deleteData() {
databaseReference.child("users/123").remove().then((_) {
print('Data deleted successfully');
}).catchError((error) {
print('Error deleting data: $error');
});
}
void listenForChanges() {
databaseReference.child("users").onValue.listen((event) {
if (event.snapshot.exists) {
setState(() {
data = 'Data updated: ${event.snapshot.value}';
});
print('Data updated: ${event.snapshot.value}');
} else {
print('No data available.');
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(data),
ElevatedButton(
onPressed: () {
createData();
},
child: Text('Create Data'),
),
ElevatedButton(
onPressed: () {
readData();
},
child: Text('Read Data'),
),
ElevatedButton(
onPressed: () {
updateData();
},
child: Text('Update Data'),
),
ElevatedButton(
onPressed: () {
deleteData();
},
child: Text('Delete Data'),
),
],
),
),
);
}
}
Conclusion
Firebase Realtime Database offers a powerful and convenient solution for managing real-time data in Flutter applications. With its simple API and real-time capabilities, developers can easily create interactive and dynamic user experiences. This guide has covered the essential steps for integrating Firebase Realtime Database into your Flutter projects, enabling you to build scalable and real-time applications with ease.