Flutter Firestore Tutorial

flutter-firestore-example
flutter-firestore-example

A Simple Chat with Flutter & FireStore

In the last article, we have seen how to implement a flutter firebase chat (real-time database). This tutorial, we’re going to implement the same concept but with firestore

Step 1: Configure Firebase & Flutter

Before starting this, You must complete: Firebase Flutter Setup

Step 2: Adding Dependencies

Once you have completed setup, we need to add required packages with your pubspec.yaml. In our case we need to add Firestore (cloud_firestore), 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">cloud_firestore</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 reference to chats collection for storing messages. & _txtCtrl for handling user inputs

<span class="hljs-attribute">var</span> _firestoreRef = Firestore.instance.collection(<span class="hljs-string">'chats'</span>);
<span class="hljs-attribute">TextEditingController</span> _txtCtrl = TextEditingController();

Now using _firestoreRef we can add, read, update, delete data with chats collection

Insert Data to Firebase FireStore

sendMessage() {
  _firestoreRef.<span class="hljs-keyword">add({
</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>
  _txtCtrl.clear()<span class="hljs-comment">;</span>
}

this code can insert(push) data into firestore & clear text field

Delete Data for FireStore

deleteMessage(<span class="hljs-built_in">key</span>) {
    _firestoreRef.document(<span class="hljs-built_in">key</span>).<span class="hljs-keyword">delete</span>();
}

Using this code, we delete document with key

Update Data to FireStore

updateTimeStamp(key) {
    <span class="hljs-attribute">_firestoreRef
        .document(key)
        .updateData({"timestamp"</span>: DateTime<span class="hljs-variable">.now</span>()<span class="hljs-variable">.millisecondsSinceEpoch</span>});
}

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>: _firestoreRef.snapshots(),
    builder: (<span class="hljs-name">context</span>, snapshot) {
        if (!snapshot.hasData)
            return LinearProgressIndicator()<span class="hljs-comment">;</span>
        else {
            List item = []<span class="hljs-comment">;</span>
            snapshot.data.documents.forEach((<span class="hljs-name">document</span>) {
                item.add({<span class="hljs-string">"key"</span>: document.documentID, ...document.data})<span class="hljs-comment">;</span>
            })<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']),
                    );
                },
            );
        }
    },
)

Explanation:

  • We created StreamBuilder based on _firestoreRef.snapshots(), which means, we update stream builder whenever data changes on fireStore Database (CRUD)
  • If there is no error, we’re storing all messages (snapshot.data.documents) into List item
  • Since firebase key are unpredictable, we have used forEach to push data into item
  • 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>

Screenshot