cofounderella/lib/services/chat/chat_service.dart

136 lines
4.4 KiB
Dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart' show debugPrint;
import '../../constants.dart';
import '../../utils/helper.dart';
import '../../models/message.dart';
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,
);
// construct chat room ID for the two users
String chatRoomID = getCompoundId([currentUserID, receiverID]);
// create batch to add message and update last message details in one step
WriteBatch batch = _firestore.batch();
// add new message to database
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();
}
/// 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());
});
}
/// Retrieves the last message of a chatroom.
///
/// Returns [null] in case of an error.
Future<Message?> getLastMessage(String chatRoomID) async {
String senderID = '';
String senderEmail = '';
String receiverID = '';
String message = '';
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();
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');
}
} catch (e) {
debugPrint('Error on getLastMessage: ${e.toString()}');
return null;
}
return Message(
senderID: senderID,
senderEmail: senderEmail,
receiverID: receiverID,
message: message,
timestamp: timestamp,
);
}
// get messages
Stream<QuerySnapshot> getMessages(String userID, otherUserID) {
String chatRoomID = getCompoundId([userID, otherUserID]);
return _firestore
.collection(Constants.dbCollectionChatRooms)
.doc(chatRoomID)
.collection(Constants.dbCollectionMessages)
.orderBy(Constants.dbFieldMessageTimestamp, descending: false)
.snapshots();
}
}