Today will discuss Chat using Firebase in Flutter. Nowadays, the Chat app is very popular. In this blog, I will show the basic chat (without authentication) application in the flutter.
Before starting this please checkout the firebase setup in the flutter project.
Let start with the programming part.
Step 1: First add dependency in pubspec.yaml
1 |
firebase_messaging: "^9.0.1" |
Step 2: Create a project in Firebase and add the bundle id on the project so that the app can access the firebase. Now, add Google-info.plist and Google-services.json in iOS and Android project directory.
Step 3: Create a widget for the message. In this example, i will handle both image and text in the same widget.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
class MessageItem extends StatelessWidget { const MessageItem( {@required this.showFriendImage, @required this.receiverId, @required this.senderId, this.message, this.imageURL}); final bool? showFriendImage; final String? receiverId; final String? message; final String? senderId; final String? imageURL; @override Widget build(BuildContext context) { var deviceData = MediaQuery.of(context).size; return Padding( padding: EdgeInsets.only( bottom: deviceData.height * 0.01, left: 8, right: 8, ), child: Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: senderId == receiverId ? MainAxisAlignment.start : MainAxisAlignment.end, children: <Widget>[ senderId == receiverId ? showFriendImage == true ? Icon( Icons.account_circle_outlined, size: 30, ) : SizedBox(width: deviceData.height * 0.045) : SizedBox.shrink(), senderId == receiverId ? SizedBox(width: deviceData.width * 0.02) : SizedBox.shrink(), Flexible( child: Container( decoration: BoxDecoration( color: MobikulTheme.accentColor .withOpacity(senderId == receiverId ? 0.1 : 0.8), borderRadius: BorderRadius.only( topLeft: Radius.circular(deviceData.width * 0.05), topRight: Radius.circular(deviceData.width * 0.05), bottomRight: Radius.circular( senderId == receiverId ? deviceData.width * 0.05 : 0), bottomLeft: Radius.circular( senderId != receiverId ? deviceData.width * 0.05 : 0), )), padding: EdgeInsets.symmetric( vertical: deviceData.height * 0.015, horizontal: deviceData.height * 0.015), child: imageURL == "" ? Text( message ?? '', style: TextStyle( fontSize: deviceData.height * 0.018, color: senderId == receiverId ? Colors.black : Colors.white, ), ) : ImageView( url: imageURL, height: 150, width: 150, ), ), ), ], ), ); } } |
Step 4: Add a List to display Messages.
1 2 3 |
CollectionReference? chatReference; chatReference = db.collection("chats").doc(widget.chatId).collection('messages'); |
1 2 3 4 |
ListView( reverse: true, children: generateMessages(snapshot), ), |
1 2 3 4 5 6 7 8 9 10 11 |
generateMessages(AsyncSnapshot<QuerySnapshot> snapshot) { return snapshot?.data!.docs ?.map<Widget>((doc) => MessageItem( showFriendImage: _showFriendImage(doc, 1), receiverId: userid, imageURL: (doc.data() as Map)['image_url'], message: (doc.data() as Map)['text'], senderId: (doc.data() as Map)['sender_id'], )) .toList(); } |
Step 5: Now add send widget with image button, TextFiled, and a send button UI. Here we have use Firebase Storage to store the image in server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
Widget _buildTextComposer() { return new IconTheme( data: new IconThemeData( color: _isWritting ? Theme.of(context).accentColor : Theme.of(context).disabledColor, ), child: new Container( margin: const EdgeInsets.symmetric(horizontal: 8.0), child: new Row( children: <Widget>[ new Container( margin: new EdgeInsets.symmetric(horizontal: 4.0), child: new IconButton( icon: new Icon( Icons.photo_camera, color: Theme.of(context).accentColor, ), onPressed: () async { var image = await ImagePicker() .getImage(source: ImageSource.gallery); int timestamp = new DateTime.now().millisecondsSinceEpoch; firebase_storage.Reference storageReference = firebase_storage.FirebaseStorage.instance.ref().child( 'chats/img_' + timestamp.toString() + '.jpg'); firebase_storage.UploadTask uploadTask = storageReference.putFile(File(image!.path)); await uploadTask.whenComplete(() async { String fileUrl = await storageReference.getDownloadURL(); _sendImage('', fileUrl); }); }), ), new Flexible( child: new TextField( controller: _textController, onChanged: (String messageText) { setState(() { _isWritting = messageText.length > 0; }); }, onSubmitted: _sendText, decoration: new InputDecoration.collapsed(hintText: "Send a message"), ), ), new Container( margin: const EdgeInsets.symmetric(horizontal: 4.0), child: getDefaultSendButton(), ), ], ), )); } |
Handle the button Event For Text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Future<Null> _sendText(String text) async { _textController.clear(); chatReference?.add({ 'text': text, 'sender_id': userid, 'sender_name': username, 'image_url': '', 'time': FieldValue.serverTimestamp(), }).then((documentReference) { print(documentReference.toString()); setState(() { _isWritting = false; }); }).catchError((e) { print(e.toString()); }); } |
Handle the button Event For image.
1 2 3 4 5 6 7 8 9 |
void _sendImage(String messageText, String imageUrl) { chatReference?.add({ 'text': messageText, 'sender_id': userid, 'sender_name': username, 'image_url': imageUrl, 'time': FieldValue.serverTimestamp(), }); } |
That’s all for the coding part now run the app.
I hope this code will help you better to understand Firebase chat in flutter. If you feel any doubt or query please comment below.
Thanks for the read this blog and if you want to visit my other blog click here.