below is my code in flutter, when I send a message all the timestamps for every message update to the current time, how do I ensure the times don't change on any old messages? I have pulled the timestamp out correctly just missing what I am doing wrong to save the individual time stamp. I am not using a firebase timestamp just using what dart gives me for DateTime
import 'dart:ffi';
import 'package:bardsf/components/card_data.dart';
import 'package:bardsf/screens/admin/admin_chat.dart';
import 'package:bardsf/screens/main_screens/qr_screen.dart';
import 'package:bardsf/screens/workouts/workout_selector.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:bardsf/components/reusable_cards.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../chat/chat_selector_screen.dart';
import 'package:bardsf/screens/chat/chat_screen.dart';
import 'package:intl/intl.dart';
late String messageText;
class HomePageScreen extends StatefulWidget {
static const String id = 'home_page_screen';
@override
_HomePageScreenState createState() => _HomePageScreenState();
}
class _HomePageScreenState extends State<HomePageScreen> {
final messageTextController = TextEditingController();
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
late User loggedInUser;
static const TextStyle optionStyle = TextStyle(
fontSize: 30, fontWeight: FontWeight.bold);
@override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e) {
print (e);
}
}
void messagesStream() async {
await for (var snapshot in _firestore.collection('messages').orderBy(
'timestamp').snapshots()) {
for (var message in snapshot.docs) {
print(message.data().cast());
}
}
}
@override
Widget build(BuildContext context) {
return Container(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/bar1.jpg"), fit: BoxFit.fill,
)
),
child: Scaffold(
backgroundColor: Colors.white.withOpacity(0.5),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ReusableCard(
colour: Colors.white,
cardChild: CardData(
label: 'The Bar',
labeltwo: 'Member Access 24/7', icon: IconData(10),
), onPress: () {},
),
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('messages').snapshots(),
builder: (context, snapshot) {
List<MessageBubble> messageBubbles = [];
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightBlueAccent,
),
);
}
final messages = snapshot.data!.docs;
for (var message in messages) {
final messageText = message['text'];
final messageSender = message['sender'];
final currentUser = loggedInUser.email;
final messageBubble = MessageBubble(
sender: 'The Bar Gym',
text: messageText,
isMe: currentUser == messageSender,
daterTimer: DateTime.now().millisecondsSinceEpoch,
);
messageBubbles.add(messageBubble);
}
return Expanded(
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Container(
color: Colors.white.withOpacity(0.6),
child: ListView(
reverse: false,
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
children: messageBubbles,
),
),
),
);
},
),
]
),
),
),
),
);
}
}
class MessageBubble extends StatelessWidget {
MessageBubble({required this.sender,required this.text,required this.isMe, required this.daterTimer });
final String sender;
final String text;
final bool isMe;
final int daterTimer;
String readTimestamp(int timestamp) {
var now = new DateTime.now();
var format = new DateFormat('M/d' ' ' 'K:m'' ''a');
var date = DateTime.fromMillisecondsSinceEpoch(timestamp);
var diff = date.difference(now);
var time = '';
if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else {
if (diff.inDays == 1) {
time = (diff.inDays/360).toString() 'DAY AGO';
} else {
time = (diff.inDays/360).toString() 'DAYS AGO';
}
}
return time;
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: isMe ? CrossAxisAlignment.stretch : CrossAxisAlignment.start,
children: <Widget>[
Row(
children: [
Expanded(
child: Text(sender,
style: TextStyle(
fontSize: 12.0,
color: Colors.red,
),
),
),
Expanded(child: Text('${readTimestamp(daterTimer)}',
style: TextStyle(color: Colors.black)
),
),
],
),
Material(
// borderRadius: isMe ? BorderRadius.only(topLeft: Radius.circular(30.0),
// bottomLeft: Radius.circular(30.0),
// bottomRight: Radius.circular(30.0),
// topRight: Radius.circular(30.0)
// ) : BorderRadius.only(topRight: Radius.circular(30.0),
// bottomLeft: Radius.circular(30.0),
// bottomRight: Radius.circular(30.0),
// topLeft: Radius.circular(30.0),
// ),
elevation: 5.0,
color: isMe ? Colors.transparent : Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
child: Text('$text',
style: TextStyle( fontSize: 15.0,
fontWeight: FontWeight.bold,
color: isMe ? Colors.white : Colors.black,),
),
),
),
],
),
);
}
}
CodePudding user response:
Your error is in this line:
daterTimer: DateTime.now().millisecondsSinceEpoch,
It seems you are overriding the value you are reading from Firestore. It should be something like this:
daterTimer: message['timestamp'];,
adjust it to your specific case
Let me know if this does not help.
Edit 1:
Basically, you are not reading the timestamp from Firestore, you are just reading the time now.
Try this:
daterTimer: (json['timestamp'] == null) ? null : (json['timestamp'] as Timestamp).toDate(),
If it does not work, you need to show me what type is 'timestamp' field in Firestore as well as the code you are using to write to Firestore.
Edit 2:
I had a typo. Try this:
daterTimer: (message['timestamp'] == null) ? null : (message['timestamp'] as Timestamp).toDate(),
CodePudding user response:
I had to change these lines and it works
daterTimer: (message['timestamp'] == null) ? null : (message['timestamp'] as Timestamp).toDate(),
final DateTime? daterTimer;
Expanded(child: Text('${daterTimer}',