How to show last messages in Flutter
Add descending: true
after timestamp.
like Expanded( child: Container( //margin: EdgeInsets.symmetric(horizontal: 5), child: StreamBuilder<QuerySnapshot>( stream: _firestore .collection("messages") .orderBy( "timestamp", descending: true ) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator( backgroundColor: kPrimaryColor, ), );
Edgar1102
Updated on December 30, 2022Comments
-
Edgar1102 over 1 year
I have this project I'm working on. It's a chat app. I've been able to handle most of the functionalities but need help with some stuff. I use firebase as backend and all data is stored and retrieved from firestore to display the messages in the chat. I noticed that on opening the chat I dont see the last message automatically the way it shows normally on whatsapp or other chat apps. For instance, if i type a new message, I want that to be the last thing that is shown on the page at the bottom. Please help me check this out. Here's my code:
import 'package:chat/constants.dart'; import 'package:chat/utilities/constants.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; import 'package:chat/models/auth.dart'; import 'package:chat/models/message.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class ChatScreen extends StatefulWidget { final AuthImplementation auth; final VoidCallback signedOut; ChatScreen({ this.auth, this.signedOut, }); @override _ChatScreenState createState() => _ChatScreenState(); } class _ChatScreenState extends State<ChatScreen> { bool show = false; FocusNode focusNode = FocusNode(); final Firestore _firestore = Firestore.instance; TextEditingController messageController = TextEditingController(); ScrollController scrollController = ScrollController(); String userName; @override void initState() { super.initState(); widget.auth.getCurrentUserEmail().then((email) { setState(() { final String userEmail = email; final endIndex = userEmail.indexOf("@"); userName = userEmail.substring(0, endIndex); focusNode.addListener(() { if (focusNode.hasFocus) { setState(() { show = false; }); } }); }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: new Container( padding: new EdgeInsets.all(8.0), decoration: new BoxDecoration( image: new DecorationImage( image: new AssetImage("assets/images/social-logo.png"), fit: BoxFit.fill), color: Colors.white, borderRadius: new BorderRadius.all(new Radius.circular(80.0)), border: new Border.all( color: Colors.white, width: 1.0, ), ), ), title: Text("One Gov FX Signal Room", style: TextStyle( fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold, fontFamily: 'Spartan', )), backgroundColor: kPrimaryColor, actions: <Widget>[ IconButton( icon: FaIcon(FontAwesomeIcons.signOutAlt), color: Colors.white, onPressed: logOut), ], ), backgroundColor: antiFlashWhite, body: WillPopScope( child: Column( children: <Widget>[ Container( color: Colors.white, padding: EdgeInsets.only(left: 10, right: 0, bottom: 10, top: 10), child: Row( children: [ CircleAvatar( backgroundColor: Colors.white, backgroundImage: AssetImage("assets/images/social-logo.png"), ), SizedBox( width: 50, ), Flexible( child: Column(children: const <Widget>[ Text('Message From the Admins'), Text( 'Keep your messages polite and do not abuse the channel. Try to keep your discussions within the community guidelines'), ]), ) ], ), ), Expanded( child: Container( //margin: EdgeInsets.symmetric(horizontal: 5), child: StreamBuilder<QuerySnapshot>( stream: _firestore .collection("messages") .orderBy( "timestamp", ) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator( backgroundColor: kPrimaryColor, ), ); List<DocumentSnapshot> docs = snapshot.data.documents; List<Widget> messages = docs .map((doc) => Message( user: doc.data['user'], text: doc.data['text'], timestamp: doc.data['timestamp'], mine: userName == doc.data['user'], )) .toList(); return ListView( controller: scrollController, children: messages, ); }), ), ), Container( color: Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Row( children: <Widget>[ IconButton( icon: FaIcon( FontAwesomeIcons.smile, color: kPrimaryColor, ), onPressed: () { focusNode.unfocus(); focusNode.canRequestFocus = false; setState(() { show = !show; }); }, ), Expanded( child: Padding( padding: const EdgeInsets.all(10), child: TextField( focusNode: focusNode, style: TextStyle( fontFamily: 'Poppins', fontSize: 15, ), onSubmitted: (value) => sendChat(), controller: messageController, scrollController: scrollController, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.newline, maxLines: null, cursorColor: kPrimaryColor, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(20)), filled: true, hintText: "Say Something. Be Nice...", hintStyle: TextStyle( fontFamily: 'Montserrat', fontSize: 12), ), ), ), ), IconButton( icon: FaIcon( FontAwesomeIcons.file, color: kPrimaryColor, ), onPressed: () { showModalBottomSheet( backgroundColor: Colors.transparent, context: context, builder: (builder) => bottomsheet()); }, ), IconButton( icon: FaIcon( FontAwesomeIcons.paperPlane, color: kPrimaryColor, ), onPressed: sendChat, ), ], ), show ? emojiSelect() : Container(), ], ), ), ], ), onWillPop: () { if (show) { setState(() { show = false; }); } else { Navigator.pop(context); } return Future.value(false); }), ); } void logOut() async { try { await widget.auth.signOut(); widget.signedOut(); } catch (e) { print("error :" + e.toString()); } } Future<void> sendChat() async { if (messageController.text.length > 0) { await _firestore.collection("messages").add({ 'user': userName, 'text': messageController.text, 'timestamp': FieldValue.serverTimestamp(), }); messageController.clear(); scrollController.animateTo(scrollController.position.maxScrollExtent, duration: Duration(milliseconds: 300), curve: Curves.easeOut); } } Widget bottomsheet() { return Container( height: 120, width: MediaQuery.of(context).size.width, child: Card( margin: EdgeInsets.all(0), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( child: iconcreation( Icons.analytics, Colors.black, "Analysis", )), SizedBox( width: 40, ), iconcreation(Icons.report, Colors.black, "Report User"), SizedBox( width: 40, ), iconcreation(Icons.link, Colors.black, "Link") ], ), ), ), ); } Widget iconcreation(IconData icon, Color color, String text) { return InkWell( onTap: () {}, child: Column( children: [ CircleAvatar( backgroundColor: color, radius: 30, child: Icon( icon, size: 29, color: Colors.white, ), ), SizedBox(height: 5), Text(text), ], ), ); } Widget emojiSelect() { return EmojiPicker( rows: 4, columns: 7, onEmojiSelected: (emoji, category) { print(emoji); setState(() { messageController.text = messageController.text + emoji.emoji; }); }); } }
Here is a sample image of the app: Screenshot of App
-
Edgar1102 almost 3 yearsThis didnt work. It only reversed the order of the messaging. It made my newly writtten messages appear at the top but didnt scroll there
-
Tarik Huber almost 3 yearsTry to remove your scroll controller and leve the reverse.