Let’s explore firebase realtime database by creating a simple chat app. where anyone can post message publically
Step 1: Configure Firebase & Flutter
Before starting this, You must complete: Firebase Flutter Setup
Step 2: Adding Dependencies
Once you have completed setup. now we can add required packages with your pubspec.yaml
. In our case, we need to add realtime database (firebase_database
), intl
(for timestamp handling)
<span class="hljs-selector-tag">dependencies</span>:
<span class="hljs-selector-tag">flutter</span>:
<span class="hljs-selector-tag">sdk</span>: <span class="hljs-selector-tag">flutter</span>
<span class="hljs-selector-tag">cupertino_icons</span>: ^0<span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.2</span>
<span class="hljs-selector-tag">firebase_core</span>: ^0<span class="hljs-selector-class">.4</span><span class="hljs-selector-class">.0</span>+6
<span class="hljs-selector-tag">firebase_database</span>: ^3<span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.4</span>
<span class="hljs-selector-tag">intl</span>: ^0<span class="hljs-selector-class">.15</span><span class="hljs-selector-class">.8</span>
Step 3: Working with Code
Now we can start writing code with our main.dart
Let’s create a db reference chat
to store our messages. & _txtCtrl
for handling user inputs
<span class="hljs-attribute">var</span> _firebaseRef = FirebaseDatabase().reference().child(<span class="hljs-string">'chats'</span>);
<span class="hljs-attribute">TextEditingController</span> _txtCtrl = TextEditingController();
Now using _firebaseRef
we can add, read, update, delete data with chat
Insert Data to Firebase Realtime Database
sendMessage() {
_firebaseRef.push()<span class="hljs-meta">.set</span>({
<span class="hljs-string">"message"</span>: _txtCtrl<span class="hljs-meta">.text</span>,
<span class="hljs-string">"timestamp"</span>: DateTime.now().millisecondsSinceEpoch
})<span class="hljs-comment">;</span>
}
this code can insert(push) data into firebase
Delete Data to Firebase Realtime Database
deleteMessage<span class="hljs-comment">(key)</span> {
_firebaseRef.child<span class="hljs-comment">(key)</span>.remove<span class="hljs-comment">()</span>;
}
Using this code, we delete child with key
Update Data to Firebase Realtime Database
updateTimeStamp(<span class="hljs-built_in">key</span>) {
_firebaseRef
.child(<span class="hljs-built_in">key</span>)
.<span class="hljs-keyword">update</span>({<span class="hljs-string">"timestamp"</span>: DateTime.now().millisecondsSinceEpoch});
}
Using this code, we’re updating the timestamp of particular message based on key
Read data from firebase Realtime Database
To display firebase data into our app, we need StreamBuilder
.
StreamBuilder(
<span class="hljs-name">stream</span>: _firebaseRef.onValue,
builder: (<span class="hljs-name">context</span>, snap) {
if (<span class="hljs-name">snap</span>.hasData <span class="hljs-symbol">&&</span> !snap.hasError <span class="hljs-symbol">&&</span> snap.data.snapshot.value != null) {
Map data = snap.data.snapshot.value<span class="hljs-comment">;</span>
List item = []<span class="hljs-comment">;</span>
data.forEach((<span class="hljs-name">index</span>, data) => item.add({<span class="hljs-string">"key"</span>: index, ...data}))<span class="hljs-comment">;</span>
return ListView.builder(
<span class="hljs-name">itemCount</span>: item.length,
itemBuilder: (<span class="hljs-name">context</span>, index) {
return ListTile(
<span class="hljs-name">title</span>: Text(<span class="hljs-name">item</span>[index]['message']),
trailing: Text(<span class="hljs-name">DateFormat</span>(<span class="hljs-string">"hh:mm:ss"</span>)
.format(<span class="hljs-name">DateTime</span>.fromMicrosecondsSinceEpoch(
<span class="hljs-name">item</span>[index]['timestamp'] * 1000))
.toString()),
onTap: () =>
updateTimeStamp(item[index]['key']),
onLongPress: () =>
deleteMessage(item[index]['key']),
);
},
);
}
else
return Text("No data");
},
)
Explanation:
- We created
StreamBuilder
based on_firebaseRef.onValue
, which means, we update stream builder whenever data changes on firebase (CRUD) - If there is an error with data or null, we display Text Widget with “No data”
- If there is no error, we’re storing all messages (
snap.data.snapshot.value
) intoMap data
- Since firebase key are unpredictable, we have used
forEach
to push data intoitem
Before
{-Lk30mSI-<span class="hljs-string">ObTUuy730c4:</span> {<span class="hljs-string">message:</span> gbrjv dl, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435680036</span>}, -<span class="hljs-string">Lk30mXd97oFihH_5MVR:</span> {<span class="hljs-string">message:</span> gbrjv dl, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435679414</span>}, -Lk30izl-<span class="hljs-string">cQ7IdtKeo4i:</span> {<span class="hljs-string">message:</span> ghrhr, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435678204</span>}}
After
[{<span class="hljs-string">key:</span> -Lk30mSI-ObTUuy730c4, <span class="hljs-string">message:</span> gbrjv dl, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435680036</span>}, {<span class="hljs-string">key:</span> -Lk30mXd97oFihH_5MVR, <span class="hljs-string">message:</span> gbrjv dl, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435679414</span>}, {<span class="hljs-string">key:</span> -Lk30izl-cQ7IdtKeo4i, <span class="hljs-string">message:</span> ghrhr, <span class="hljs-string">timestamp:</span> <span class="hljs-number">1563435678204</span>}]
- Once everything is fine, we use
ListView.builder()
& ListTile for displaying data - When user Tap, we update timestamp & with longpress, we delete data
This code we display a TextField with Buttons
Container( <span class="hljs-name">child</span>: Row(<span class="hljs-name">children</span>: <Widget>[
Expanded(<span class="hljs-name">child</span>: TextField(<span class="hljs-name">controller</span>: _txtCtrl)),
SizedBox(
<span class="hljs-name">width</span>: <span class="hljs-number">80</span>,
child: OutlineButton(<span class="hljs-name">child</span>: Text(<span class="hljs-string">"Add"</span>), onPressed: () => sendMessage()))
])
)<span class="hljs-comment">;</span>