Hello Guys,
Clients nowadays expect their software to respond quickly and provide immediate feedback. Gone are the days when you could refresh your app every minute or provide your users an icon to update it themselves: now they demand SPEED!
Firebase Real-time Database can help with this. To imitate re-activeness, you no longer need to develop sophisticated apps with thousands of lines of async activities and threaded processes. You’ll be up and operating in no time with Real-time Database.
Today, you’ll design the pinnacle of reactive software: Chatting, an instant messaging program. You’ll learn the following things while making Chatting:
- When should you use a Real-time Database?
- The procedures for creating a Firebase project that uses the Real-time Database.
- How to connect to the Real-time Database, query it, and populate it.
- How to create your own instant messaging program using the Real-time Database.
What is the definition of a Real-time database?
Within the Firebase set of technologies, Google offers two real-time sync databases: Cloud Fire-store and Firebase Real-time Database. What’s the difference, though?
Google’s newest service is called Fire-store. They designed Fire-store in order to better deal with large-scale software that contains a lot of layered data. It can query and return each data document separately, resulting in a truly elastic environment that can keep up with your growing data set. Despite being a document-driven No-SQL database, a Real-time Database returns data in JSON format. When you query a JSON data tree, all of its child nodes are returned as well. Keep your data hierarchy as flat as possible to keep your transactions light and nimble. Both of these database options are excellent, so knowing when to use them is crucial. For each database, below are some key metrics:
Cloud Fire-store
- Has a free plan, but if the limit is reached, it charges each transaction and, to a lesser extent, per storage used.
- It’s a lot easier to scale.
- Can work with large, multi-layered data collections and relationships.
- Mobile and online versions are both available.
Firebase Real-time Database
- Has a free plan as well, but costs for storage are utilized rather than queries done after the limit has been reached.
- The latency is quite low.
- JSON makes it simple to store simple data.
- Only for mobile devices.
You’ll perform a lot of transactions and save simple data in a chat app without having to do any sophisticated queries. A real-time Database is an obvious choice because it is less expensive, easier to use, and runs faster.
On Google’s product page, you can get a complete list of comparisons. If you want to learn more about the Fire-store solution, go to our Cloud Fire-store tutorial.
Creating a Google Project with a Database
You must first create a project on the Firebase Console before using any of Google’s cloud services. Then you may create and maintain your Real-time Database directly from the console.
Click Create a project in the Firebase Console.
Then give your project the name Chatting and click Next.
You don’t need Google Analytics for this lesson, so turn it off. Finally, at the bottom of the page, click Create project.
Give Google a minute to load before starting your project. Woohoo!
Return to your Firebase home page and select See all Build features to start building your Real-time Database.
Click Real-time Database and select Create Database.
Select the country where the data will be stored, and then select Start in test mode. Starting in test mode assures that you can quickly read and write data while working on your app. Then select Enable from the drop-down menu.
You’ll arrive at your database console once your database is finished. You can return to this page later to see the data from your app in real time.
The next step is to link your Flutter app to your new Google project.
Creating Files for Google Services
Google uses a config file that contains all of your Firebase project’s API keys. You’ll need to make separate config files for your Android and iOS apps. Let’s begin with Android.
Setting Up Android
Make sure Chatting is selected as your current project on the Firebase console’s main page. Then, on the Android symbol, click.
This will send you to a page that will assist you in preparing your Android configuration file. com.example.chatting should be added. In the package name field, type Chatting, and in the nickname field, type Chatting. Then select Register app from the drop-down menu.
Allow a few moments for the file to generate. Then select Google-services.json from the drop-down menu.
Google-services.json should be saved to android/app.
Open android/build.gradle in your project. Then, in the dependencies section of build script, add the following dependent at the end of the list:
classpath 'com.google.gms:google-services:4.3.8'
Now open android/app/build.gradle and add the Google services plugin after the other apply plugins.
apply plugin: 'com.google.gms.google-services'
Now it’s time to move on to iOS!
Setting Up iOS
To set up your iOS project, you’ll need Xcode. If you don’t have a Mac, you may skip this part and focus on the Android app instead.
Return to the Firebase Console’s main page and select Add app. Then choose iOS.
This will take you to the iOS config file generating page. Add com.example.chatting as your iOS Bundle ID and Chatting as your app username, just as before.
Download GoogleService-info.plist and register your app.
GoogleService-info.plist should be saved in ios/Runner. Then, in Xcode, open the ios folder for your project.
Right-click Runner in Xcode and select Add Files to “Runner.”
Then, from Runner, choose Google-Services-Info.plist. Check that Copy items if necessary is selected. Then press the Add button.
And that’s all there is to it! Xcode should be closed. You may now communicate with your Google project from both your iOS and Android Flutter apps.
It’s time to get to work on some programming.
Flutter Dependencies Are Being Added
Begin by including firebase core and firebase database as dependencies in your pubspec.yaml file. Put them at the bottom of the list of dependencies:
firebase_core: 1.3.0 firebase_database: 7.1.1
The Data Modeling
To reflect the structure of your chat app messages, you must construct a data model. You’ll also create a Data Access Object (DAO) that can store and retrieve messages from your Realtime Database in addition to the data model.
Inside lib, create a new folder called data. This is where you’ll keep your data models and data access objects.
Including a Data Model
Make a new file called message.dart in data. Then create a new class that has two fields, text and date:
class Message { final String text; final DateTime date; Message(this.text, this.date); }
You’ll also need a method to convert your Message model from JSON, which is how it’s stored in your Realtime Database. At the bottom of your class, add two JSON converter methods:
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 assist you in converting the JSON from the Realtime Database into a Message. The second will do the inverse, converting the Message to JSON for saving.
Introducing a Data Access Object
Make a new file called message dao.dart in data. This is your message-handling DAO.
Import message.dart and firebase_database.dart. Then, make a DatabaseReference that points to 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 searches your Realtime Database for a JSON document called messages. Firebase will create it if it does not already exist. MessageDao is now required to perform two functions: saving and retrieving. Add a save message function to the bottom of your class.
void saveMessage(Message message) { _messagesRef.push().set(message.toJson()); }
This function takes a Message as a parameter and saves the JSON message to your Realtime Database using your DatabaseReference. Yes, there is only one line of code.
Because you’ll be using a cool widget called a FirebaseAnimatedList that interacts directly with your DatabaseReference, you only need to expose a Query for the retrieval method.
Add the following function to your MessageDao: getMessageQuery()
Query getMessageQuery() { return _messagesRef; }
Okay, DAO, you now have your message. The data access object, as the name implies, allows you to access any data stored at the given Realtime Database reference. As you send messages, it will also allow you to save new data. All that remains is to create your user interface.
Adding New Messages
Open messag_list.dart and add the imports Message and MessageDao at the top of the file:
import 'data/message.dart'; import 'data/message_dao.dart';
Then, within MessageList, create a MessageDao by replacing // TODO 1 with:
final messageDao = MessageDao();
Now, at // TODO 2, replace _sendMessage 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 generates a new Message with the _messageController text from your widget tree. It then saves that message to your Realtime Database using your MessageDao. Try typing your first message and then clicking Send.
Return to your Firebase Console and open the Realtime Database for your project. Your message will appear as an entry.
Exciting! Applaud yourself for a job well done.
Attempt to add a few more messages. You can even keep an eye on your Realtime Database as you enter each message to see it appear in real-time
Messages Are Displayed Reactively
As previously stated, you will display your messages using FirebaseAnimatedList. This Widget, provided by the Realtime Database Flutter API, makes it simple to display lists from your Realtime Database. It’s so simple to use that you’ll never go back to traditional mobile development.
Add the following imports to the top of the message list.dart for firebase animated list.dart:
import 'package:firebase_database/ui/firebase_animated_list.dart';
Then, at // TODO 3, replace _getMessageList with this code, which 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); }, ), ); }
A Query is required by FirebaseAnimatedList, which your MessageDao can happily provide via getMessageQuery. That query is used to retrieve messages from your Realtime Database.
The item builder from FirebaseAnimatedList triggers and returns message data in JSON format for each message returned. The JSON is then converted to a Message, and your message model builds and returns a MessageWidget.
Create and run. Your messages will be displayed in a list: