Open ak2766 opened 4 years ago
After thinking this through a little bit before embarking on coding (just by looking at the order in which they appear in Firebase), it seems the real solution is to add a timestamp to each message, then on retrieval, sort the messages based on the timestamp before adding them to the messageBubbles
list.
can you share the code after your update @ak2766
I added timestamp into the code and it worked. @FadyWaheed11 chat_screen.txt
I used DateTime into the code and it works well. chat_screen.txt
@FadyWaheed11
can you share the code after your update @ak2766
Apologies, I got busy and haven't returned to this, but I see others had the same idea and already have a solution. Hopefully that works for you too.
Thanks bro it works @ak2766
Hello guys, I know it's been a while but can I add something?
With the method you proposed, if someone with a phone clock which is not accurate it will mess up the order, right? I know that will be rare but it's something we should think about.
Hello guys, I know it's been a while but can I add something?
With the method you proposed, if someone with a phone clock which is not accurate it will mess up the order, right? I know that will be rare but it's something we should think about.
If use unix time instead of phone clock it works well.
Use This Code after clearing your all old Database message and Data from firebase cloud DataBase . Once you clear all the previous data from database, you can you this code . credit :- @koorosh-k98,
`import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import '../constants.dart';
final _firestore = Firestore.instance; FirebaseUser loggedInUser;
class ChatScreen extends StatefulWidget { static const String id = 'chat_screen'; @override _ChatScreenState createState() => _ChatScreenState(); }
class _ChatScreenState extends State
String messageText;
@override void initState() { super.initState();
getCurrentUser();
}
void getCurrentUser() async { try { final user = await _auth.currentUser(); if (user != null) { loggedInUser = user; } } catch (e) { print(e); } }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions:
class MessagesStream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder
final currentUser = loggedInUser.email;
final messageBubble = MessageBubble(
sender: messageSender,
text: messageText,
isMe: currentUser == messageSender,
dateTime: messageDateTime,
);
messageBubbles.add(messageBubble);
messageBubbles.sort((a, b) =>
DateTime.parse(b.dateTime).compareTo(DateTime.parse(a.dateTime)));
}
return Expanded(
child: ListView(
reverse: true,
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
children: messageBubbles,
),
);
},
);
} }
class MessageBubble extends StatelessWidget { MessageBubble({this.sender, this.text, this.isMe, this.dateTime});
final String sender; final String text; final String dateTime; final bool isMe;
@override
Widget build(BuildContext context) {
print(dateTime);
return Padding(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment:
isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children:
Expanded( child: TextField( controller: messageTextController, onChanged: (value) { messageText = value; },
very good,Thanks
TimeStamp or DateTime is not proper method to sorting messages because i give one example, So there are two Devices, DeviceA and DeviceB both install this App but DeviceA's time is 10:45 and DeviceB's time is 10:50 so messages not sorting properly, my suggestion is to use this below method to work properly...
onPressed: () { messageTextController.clear(); _firestore.collection('messages').add({ 'text': messageText, 'sender': loggedInUser.email, 'timestamp': FieldValue.serverTimestamp(),
});
},
class MessagesStream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder
( Highlight of Sorting method above code:- 'timestamp': FieldValue.serverTimestamp(),
_firestore .collection('messages') .orderBy('timestamp', descending: false) .snapshots(), ) I used this this methos and its work properly, I hope this will help you! Thank you
@RahiPatel25 Thank you. This fixed the sorting issue as well as an issue with messages grouping together out of order, AND by the sender. For the sake of making your comment a little easier to read I will include the code that worked for me below...
The two major components being:
'timestamp': FieldValue.serverTimestamp(),
and
.orderBy('timestamp', descending: false)
In your chat_screen.dart file...
onPressed: () {
messageTextController.clear();
_firestore.collection('messages').add({
'text': messageText,
'sender': loggedInUser.email,
'timestamp': FieldValue.serverTimestamp(),
});
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
// further down in your code...
return StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('messages')
.orderBy('timestamp', descending: false)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightBlueAccent,
),
);
I even could not open, when I run code, and tried to open on my phone it stoppes doesnt open why this could be?
Flutter has changed many things over the past few years along with class names and different objects. Use this code to sort the most recent messages import 'package:flutter/material.dart'; import 'package:chat_application/constants.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
final _fireStore = FirebaseFirestore.instance; final _auth = FirebaseAuth.instance; User loggedInUser;
class ChatScreen extends StatefulWidget { static const String id = 'chat_screen';
@override _ChatScreenState createState() => _ChatScreenState(); }
class _ChatScreenState extends State
String messageText;
@override void initState() { super.initState(); getCurrentUser(); }
void getCurrentUser() async { try { final user = _auth.currentUser; if (user != null) { loggedInUser = user; } } catch (e) { print(e); } }
void messagesStream() async { await for (var snapshot in _fireStore.collection('messages').snapshots()) { for (var message in snapshot.docs) { print(message.data()); } } }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions:
class MessagesStream extends StatelessWidget { const MessagesStream({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder
class MessageBubble extends StatelessWidget { final String sender; final String text; final String dateTime; final bool isMe; MessageBubble(this.text, this.sender, this.isMe, this.dateTime); @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.all(10.0), child: Column( crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ Text( sender, style: TextStyle( color: Colors.black54, fontSize: 12.0, ), ), Material( color: isMe ? Colors.lightBlueAccent : Colors.white, elevation: 5.0, borderRadius: isMe ? BorderRadius.only( topLeft: Radius.circular(30.0), bottomLeft: Radius.circular(30.0), bottomRight: Radius.circular(30.0), ) : BorderRadius.only( topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0), bottomRight: Radius.circular(30.0), ), child: Padding( padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), child: Text( text, style: TextStyle( color: isMe ? Colors.white : Colors.black, fontSize: 15.0, ), ), ), ), ], ), ); } }
Hey I'm working on an almost same app, the order is still very unpredictable even with those two reverse conditions.
Great , it works ,and me also Thanks guys
Just wanted to state that my final chat_screen code is exactly identical to your final project but the sorting of messages isn't working as intended - both on the emulator and on my Galaxy S8+. See screenshots below. There's something very odd happening here.
Will try and fix it on my own and report back here.
I've included a number (1-8) either at the beginning or at the end of the chat message to allow you to follow message post chronology.
Emulator:
Galaxy S8: