2024-04-30 19:25:16 +02:00
|
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
2024-06-06 18:45:23 +02:00
|
|
|
import 'package:flutter/foundation.dart' show debugPrint;
|
2024-04-30 19:25:16 +02:00
|
|
|
|
2024-05-25 13:56:45 +02:00
|
|
|
import '../../constants.dart';
|
2024-05-27 14:40:46 +02:00
|
|
|
import '../../utils/helper.dart';
|
2024-05-25 13:56:45 +02:00
|
|
|
import '../../models/message.dart';
|
|
|
|
|
2024-04-30 19:25:16 +02:00
|
|
|
class ChatService {
|
|
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
|
|
final FirebaseAuth _auth = FirebaseAuth.instance;
|
|
|
|
|
|
|
|
// send message
|
|
|
|
Future<void> sendMessage(String receiverID, message) async {
|
|
|
|
// get current user info
|
|
|
|
final String currentUserID = _auth.currentUser!.uid;
|
|
|
|
final String currentUserEmail = _auth.currentUser!.email!;
|
|
|
|
final Timestamp timestamp = Timestamp.now();
|
|
|
|
|
|
|
|
// create new message
|
|
|
|
Message newMessage = Message(
|
|
|
|
senderID: currentUserID,
|
|
|
|
senderEmail: currentUserEmail,
|
|
|
|
receiverID: receiverID,
|
|
|
|
message: message,
|
|
|
|
timestamp: timestamp,
|
|
|
|
);
|
|
|
|
|
2024-05-25 13:56:45 +02:00
|
|
|
// construct chat room ID for the two users
|
|
|
|
String chatRoomID = getCompoundId([currentUserID, receiverID]);
|
2024-04-30 19:25:16 +02:00
|
|
|
|
2024-06-03 16:35:33 +02:00
|
|
|
// create batch to add message and update last message details in one step
|
|
|
|
WriteBatch batch = _firestore.batch();
|
|
|
|
|
2024-05-05 10:26:49 +02:00
|
|
|
// add new message to database
|
2024-06-03 16:35:33 +02:00
|
|
|
var newMessageRef = _firestore
|
|
|
|
.collection(Constants.dbCollectionChatRooms)
|
|
|
|
.doc(chatRoomID)
|
|
|
|
.collection(Constants.dbCollectionMessages)
|
|
|
|
.doc(); // doc generates a random ID for the message
|
|
|
|
batch.set(newMessageRef, newMessage.toMap());
|
|
|
|
|
|
|
|
// update last message details in chat room
|
|
|
|
var chatRoomRef =
|
|
|
|
_firestore.collection(Constants.dbCollectionChatRooms).doc(chatRoomID);
|
|
|
|
|
|
|
|
// add to batch above
|
|
|
|
batch.set(
|
|
|
|
chatRoomRef,
|
|
|
|
{
|
|
|
|
Constants.dbFieldMessageSenderId: currentUserID,
|
|
|
|
Constants.dbFieldMessageSenderEmail: currentUserEmail,
|
|
|
|
Constants.dbFieldMessageTimestamp: timestamp,
|
|
|
|
},
|
|
|
|
SetOptions(merge: true));
|
|
|
|
|
|
|
|
// commit batch
|
|
|
|
await batch.commit();
|
|
|
|
}
|
|
|
|
|
2024-06-18 11:55:06 +02:00
|
|
|
/// Retrieves a stream of the last message of a chatroom.
|
|
|
|
Stream<Message?> getLastMessageStream(String chatRoomID) {
|
|
|
|
return _firestore
|
|
|
|
.collection(Constants.dbCollectionChatRooms)
|
|
|
|
.doc(chatRoomID)
|
|
|
|
.collection(Constants.dbCollectionMessages)
|
|
|
|
.orderBy(Constants.dbFieldMessageTimestamp, descending: true)
|
|
|
|
.limit(1)
|
|
|
|
.snapshots()
|
|
|
|
.map((snapshot) {
|
|
|
|
if (snapshot.docs.isEmpty) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var lastMessageDoc = snapshot.docs.first;
|
|
|
|
return Message.fromMap(lastMessageDoc.data());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-06-03 16:35:33 +02:00
|
|
|
/// Retrieves the last message of a chatroom.
|
2024-06-06 18:45:23 +02:00
|
|
|
///
|
|
|
|
/// Returns [null] in case of an error.
|
|
|
|
Future<Message?> getLastMessage(String chatRoomID) async {
|
2024-06-03 16:35:33 +02:00
|
|
|
String senderID = '';
|
|
|
|
String senderEmail = '';
|
|
|
|
String receiverID = '';
|
|
|
|
String message = '';
|
2024-06-06 18:45:23 +02:00
|
|
|
Timestamp timestamp = Timestamp.fromMillisecondsSinceEpoch(0);
|
|
|
|
|
|
|
|
try {
|
|
|
|
QuerySnapshot messageSnapshot = await _firestore
|
|
|
|
.collection(Constants.dbCollectionChatRooms)
|
|
|
|
.doc(chatRoomID)
|
|
|
|
.collection(Constants.dbCollectionMessages)
|
|
|
|
.orderBy(Constants.dbFieldMessageTimestamp, descending: true)
|
|
|
|
.limit(1)
|
|
|
|
.get();
|
|
|
|
|
2024-06-18 11:55:06 +02:00
|
|
|
if(messageSnapshot.docs.isNotEmpty) {
|
|
|
|
DocumentSnapshot lastMessageDoc = messageSnapshot.docs.first;
|
|
|
|
if (lastMessageDoc.exists) {
|
|
|
|
senderID = lastMessageDoc[Constants.dbFieldMessageSenderId];
|
|
|
|
senderEmail = lastMessageDoc[Constants.dbFieldMessageSenderEmail];
|
|
|
|
receiverID = lastMessageDoc[Constants.dbFieldMessageReceiverId];
|
|
|
|
message = lastMessageDoc[Constants.dbFieldMessageText];
|
|
|
|
timestamp = lastMessageDoc[Constants.dbFieldMessageTimestamp];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrint('Info: getLastMessage -> messageSnapshot is EMPTY');
|
2024-06-06 18:45:23 +02:00
|
|
|
}
|
|
|
|
} catch (e) {
|
2024-06-18 11:55:06 +02:00
|
|
|
debugPrint('Error on getLastMessage: ${e.toString()}');
|
2024-06-06 18:45:23 +02:00
|
|
|
return null;
|
2024-06-03 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return Message(
|
|
|
|
senderID: senderID,
|
|
|
|
senderEmail: senderEmail,
|
|
|
|
receiverID: receiverID,
|
|
|
|
message: message,
|
|
|
|
timestamp: timestamp,
|
|
|
|
);
|
2024-04-30 19:25:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// get messages
|
|
|
|
Stream<QuerySnapshot> getMessages(String userID, otherUserID) {
|
2024-05-25 13:56:45 +02:00
|
|
|
String chatRoomID = getCompoundId([userID, otherUserID]);
|
2024-04-30 19:25:16 +02:00
|
|
|
|
|
|
|
return _firestore
|
2024-05-05 10:26:49 +02:00
|
|
|
.collection(Constants.dbCollectionChatRooms)
|
2024-04-30 19:25:16 +02:00
|
|
|
.doc(chatRoomID)
|
2024-05-05 10:26:49 +02:00
|
|
|
.collection(Constants.dbCollectionMessages)
|
2024-06-03 16:35:33 +02:00
|
|
|
.orderBy(Constants.dbFieldMessageTimestamp, descending: false)
|
2024-04-30 19:25:16 +02:00
|
|
|
.snapshots();
|
|
|
|
}
|
|
|
|
}
|