Firebase Realtime Database Tutorial for Flutter
Get started with Firebase Realtime Database by building a chat app in Flutter that provides instant updates to connected devices. By Vincenzo Guzzi.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Firebase Realtime Database Tutorial for Flutter
15 mins
- Getting Started
- What is a Realtime Database?
- Setting up a Google Project and Database
- Creating Google Services Files
- Setting Up Android
- Setting Up iOS
- Adding the Flutter Dependencies
- Modeling the Data
- Adding a Data Model
- Adding a Data Access Object
- Creating New Messages
- Reactively Displaying Messages
- Where to Go From Here?
Adding the Flutter Dependencies
Start by adding a dependency for firebase_core and firebase_database in your pubspec.yaml. Add them to the bottom of dependencies
:
firebase_core: 1.3.0
firebase_database: 7.1.1
You’ll use them in a bit.
Modeling the Data
You have to create a data model to reflect the structure of your chat app messages. In addition to the data model, you’ll make a Data Access Object (DAO) that can store and retrieve the messages from your Realtime Database.
Add a new folder inside lib called data. You’ll use this folder to store your data models and data access objects.
Adding a Data Model
Create a new file in data called message.dart. Then add a new class with two fields, text
and date
:
class Message {
final String text;
final DateTime date;
Message(this.text, this.date);
}
You also need a way to transmute your Message
model from JSON since that’s how it’s stored in your Realtime Database. Add two JSON converter methods to the bottom of your class:
Message.fromJson(Map<dynamic, dynamic> json)
: date = DateTime.parse(json['date'] as String),
text = json['text'] as String;
Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{
'date': date.toString(),
'text': text,
};
The first definition will help you transform the JSON you receive from the Realtime Database, into a Message
. The second will do the opposite — transform the Message
into JSON, for saving.
Adding a Data Access Object
Create a new file in data called message_dao.dart. This is your DAO for your messages.
Import firebase_database.dart and message.dart. Then create a DatabaseReference
which references a node called messages
.
import 'package:firebase_database/firebase_database.dart';
import 'message.dart';
class MessageDao {
final DatabaseReference _messagesRef =
FirebaseDatabase.instance.reference().child('messages');
}
This code looks for a JSON document inside your Realtime Database called messages
. If it doesn’t exist, Firebase will create it.
Now you need MessageDao
to perform two functions: saving and retrieving. Add a new function named saveMessage
to the bottom of your class.
void saveMessage(Message message) {
_messagesRef.push().set(message.toJson());
}
This function takes a Message
as a parameter and uses your DatabaseReference
to save the JSON message to your Realtime Database. Yep, it’s only one line of code.
For the retrieval method you only need to expose a Query
since you’ll use a cool widget called a FirebaseAnimatedList which interacts directly with your DatabaseReference
.
Add a getMessageQuery()
to your MessageDao
:
Query getMessageQuery() {
return _messagesRef;
}
Alright, now you have your message DAO. As the name states, the data access object helps you access whatever data you have stored at the given Realtime Database reference. It will also let you store new data, as you send messages. Now all you have to do is build your UI.
Creating New Messages
Open message_list.dart and add Message
and MessageDao
as imports at the top of the file:
import 'data/message.dart';
import 'data/message_dao.dart';
The create a MessageDao
inside MessageList
, replacing // TODO 1
with:
final messageDao = MessageDao();
Now replace _sendMessage
at // TODO 2
with your send message code:
void _sendMessage() {
if (_canSendMessage()) {
final message = Message(_messageController.text, DateTime.now());
widget.messageDao.saveMessage(message);
_messageController.clear();
setState(() {});
}
}
This code creates a new Message
with the _messageController
text populated by a TextField
in your widget tree. It then uses your MessageDao
to save that message to your Realtime Database.
Build and run. You’ll see the same screen as you did before:
Try typing in your first message and click Send.
Now go back to your Firebase Console and open your project’s Realtime Database. You’ll see your message as an entry.
Exciting! Pat yourself on the back for a job well done.
Try adding a few more messages. You can even watch your Realtime Database as you enter each message to see them appear in real time. Pretty cool.
Now you can get to work on displaying those messages.
Reactively Displaying Messages
As previously mentioned, you’ll use FirebaseAnimatedList to display your messages. This Widget
, provided by the Realtime Database Flutter API, makes displaying lists from your Realtime Database a breeze. It’s so plug-and-play, you’ll never go back to traditional mobile development again.
RecyclerViews
? UICollectionViews
? Psshh, who needs ’em!
Add the imports for firebase_animated_list.dart at the top of message_list.dart:
import 'package:firebase_database/ui/firebase_animated_list.dart';
Then replace _getMessageList
at // TODO 3
with this code that uses FirebaseAnimatredList
:
Widget _getMessageList() {
return Expanded(
child: FirebaseAnimatedList(
controller: _scrollController,
query: widget.messageDao.getMessageQuery(),
itemBuilder: (context, snapshot, animation, index) {
final json = snapshot.value as Map<dynamic, dynamic>;
final message = Message.fromJson(json);
return MessageWidget(message.text, message.date);
},
),
);
}
FirebaseAnimatedList
requires a Query
, which your MessageDao
can happily provide via getMessageQuery
. It uses that query to get the messages from your Realtime Database.
For each message returned, the itemBuilder
from FirebaseAnimatedList
triggers and provides message data in JSON form. Then the JSON converts to a Message
and your message model constructs and returns a MessageWidget
.
Build and run. You’ll see your messages in a list:
Enter a new message, and you’ll see it appear before your eyes.
Magic.
Try loading your app on two different devices or simulators and watch in awe as you communicate in real time. Who knows, maybe you’ll release the next WhatsApp?
Where to Go From Here?
Download the completed version of the project by clicking Download Materials at the top or bottom of this tutorial. Remember, you’ll need to add your own Google Services config file for the project to build successfully.
You don’t have to use FirebaseAnimatedList
. If you need to write something more custom, you can go down to a more traditional Stream
approach and write the reactive part yourself using setState
or StreamBuilder
.
Your _databaseReference
has access to a method called onValue
that returns a Stream
directly. Use this if you would like to integrate with BLoC, Provider or RxDart.
There are plenty of other Realtime Database features which can super-charge your app and give it enterprise-grade features. These include:
- Offline capabilities: All your data stays in sync even when offline.
- Database Rules: Makes your database more secure than Fort Knox.
There are plenty of other great Firebase products you can integrate with. Check out the rest of the Firebase API. Or read our Cloud Firestore tutorial.
Leave a comment below if you have any questions!