ADD : Discplay messages in the views
continuous-integration/drone/push Build is passing Details

#MSG01/chat_firebase
Audric SABATIER 2 years ago
parent 27e970a3b9
commit bd1e2efa2e

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dafl_project_flutter/firebase_services/notification_service.dart';
import 'package:dafl_project_flutter/model/message.dart'; import 'package:dafl_project_flutter/model/message.dart';
import 'package:dafl_project_flutter/firebase_services/message_database_services.dart'; import 'package:dafl_project_flutter/firebase_services/message_database_services.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -16,6 +17,7 @@ class Controller {
static Loader loader = DatabaseLoader(); static Loader loader = DatabaseLoader();
static final Searcher _searcher = DatabaseSearcher(); static final Searcher _searcher = DatabaseSearcher();
final MessageDatabaseServices _messageAccess = MessageDatabaseServices(); final MessageDatabaseServices _messageAccess = MessageDatabaseServices();
final NotificationService _notificationService = NotificationService();
late BuildContext navigatorKey; late BuildContext navigatorKey;
@ -23,14 +25,15 @@ class Controller {
Controller() { Controller() {
currentUser = User('', ''); //TODO : remove this line currentUser = User('', ''); //TODO : remove this line
NotificationService.initialize();
} }
void sendMessage(Message message, String idSender, String idReceiver) { void sendMessage(Message message, String idSender, String idReceiver) {
_messageAccess.sendMessage(message, idSender, idReceiver); _messageAccess.sendMessage(message, idSender, idReceiver);
} }
Stream<List<Message>> getMessage(String chatId){ Stream<List<Message>> getMessage(String idSender, String idReceiver) {
return _messageAccess.getMessage(chatId); return _messageAccess.getMessage(idSender, idReceiver);
} }
void save(User userToSave) { void save(User userToSave) {

@ -1,30 +1,28 @@
import 'package:dafl_project_flutter/model/message.dart'; import 'package:dafl_project_flutter/model/message.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
class MessageDatabaseServices { class MessageDatabaseServices {
// Make an unique chat ID between 2 client. Look like 'User1-User2' // Make an unique chat ID between 2 client. Look like 'User1-User2'
static String getChatId(String idSender, String idReceiver){ String _getChatId(String idSender, String idReceiver) {
// Test to always have the same id // Test to always have the same id
if (idSender.hashCode <= idReceiver.hashCode) if (idSender.hashCode <= idReceiver.hashCode)
return '$idSender-${idReceiver}'; return '$idSender-${idReceiver}';
else else
return '${idReceiver}-$idSender'; return '${idReceiver}-$idSender';
} }
// Send a message from an user to an other // Send a message from an user to an other
void sendMessage(Message message, String idSender, String idReceiver) { void sendMessage(Message message, String idSender, String idReceiver) {
String chatId = getChatId(idSender, idReceiver); String chatId = _getChatId(idSender, idReceiver);
var documentReference = FirebaseFirestore.instance var documentReference = FirebaseFirestore.instance
.collection('messages') .collection('messages')
.doc(chatId) .doc(chatId)
.collection(chatId) .collection(chatId)
.doc(DateTime.now().millisecondsSinceEpoch.toString()); .doc(DateTime
.now()
.millisecondsSinceEpoch
.toString());
FirebaseFirestore.instance.runTransaction((transaction) async { FirebaseFirestore.instance.runTransaction((transaction) async {
transaction.set(documentReference, message.toHashMap()); transaction.set(documentReference, message.toHashMap());
@ -34,8 +32,7 @@ class MessageDatabaseServices{
// Get a message from a snapshot Firestore // Get a message from a snapshot Firestore
Message _getMessage(DocumentSnapshot<Map<String, dynamic>> snapshot) { Message _getMessage(DocumentSnapshot<Map<String, dynamic>> snapshot) {
var data = snapshot.data(); var data = snapshot.data();
if (data == null) if (data == null) throw Exception("no data in database");
throw Exception("no data in database");
return Message.fromMap(data); return Message.fromMap(data);
} }
@ -48,11 +45,14 @@ class MessageDatabaseServices{
} }
// Get the massages from Firestore // Get the massages from Firestore
Stream<List<Message>> getMessage(String chatId) { Stream<List<Message>> getMessage(String idSender, String idReceiver) {
String chatId = _getChatId(idSender, idReceiver);
return FirebaseFirestore.instance return FirebaseFirestore.instance
.collection('messages') .collection('messages')
.doc(chatId) .doc(chatId)
.collection(chatId) .collection(chatId)
.snapshots().map(_getAllMessages); .snapshots()
.map(_getAllMessages);
} }
} }

@ -0,0 +1,21 @@
import 'package:firebase_messaging/firebase_messaging.dart';
class NotificationService {
static void initialize() {
FirebaseMessaging.instance.requestPermission();
FirebaseMessaging.onMessage.listen((event) {
print('A new onMessage event was published!');
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
});
}
static Future<String?> getToken() async {
return FirebaseMessaging.instance.getToken(
vapidKey:
"BOxfduRivQnT8TS1h9WRGEk4gV2IOzJpTCcoKxVTMgVWjxi6TUcQBng2mqM7fUfNy51esFrRGE68coa0XZaKdHc");
}
}

@ -1,19 +1,34 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'dart:math'; import 'dart:math';
import 'package:dafl_project_flutter/firebase_options.dart';
import './views/pages/home/p_home.dart'; import './views/pages/home/p_home.dart';
import './views/pages/main/p_main.dart'; import './views/pages/main/p_main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rive/rive.dart' as riv; import 'package:rive/rive.dart' as riv;
import '../controller/controller.dart'; import 'controller/controller.dart';
import 'model/spot.dart'; import 'model/spot.dart';
import 'api/api.dart'; import 'api/api.dart';
import 'dart:developer' as dev; import 'dart:developer' as dev;
import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Background message ${message.messageId}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
void main() {
runApp(const MyApp()); runApp(const MyApp());
} }

@ -5,12 +5,12 @@ class Message {
String idReceiver; String idReceiver;
String content; String content;
Message({required this.idSender, Message({
required this.idSender,
required this.idReceiver, required this.idReceiver,
required this.content required this.content,
}); });
Map<String, dynamic> toHashMap() { Map<String, dynamic> toHashMap() {
return { return {
'idSender': idSender, 'idSender': idSender,
@ -19,7 +19,6 @@ class Message {
}; };
} }
factory Message.fromMap(Map<String, dynamic> data) { factory Message.fromMap(Map<String, dynamic> data) {
return Message( return Message(
idSender: data['idSender'], idSender: data['idSender'],
@ -27,4 +26,9 @@ class Message {
content: data['content'], content: data['content'],
); );
} }
@override
String toString() {
return "idSender : $idSender " + "Content : $content \n";
}
} }

@ -11,7 +11,6 @@ class User {
int test = 0; int test = 0;
//attributes from DAFL //attributes from DAFL
late int idDafl;
late String usernameDafl; late String usernameDafl;
late String passwDafl; late String passwDafl;
List<Music> discovery = []; List<Music> discovery = [];
@ -22,6 +21,7 @@ class User {
late Music _currentMusic; late Music _currentMusic;
bool sortChoise = true; bool sortChoise = true;
//constructors //constructors
User(this.usernameDafl, this.passwDafl) { User(this.usernameDafl, this.passwDafl) {
actualiseCurrentMusic(); actualiseCurrentMusic();

@ -18,12 +18,9 @@ class _ConversationPageState extends State<ConversationPage> {
final messageTextField = TextEditingController(); final messageTextField = TextEditingController();
void sendMessage(String content, String idSender, String idReceiver) { void sendMessage(String content, String idSender, String idReceiver) {
Message messageToSend = Message( Message messageToSend =
idSender: idSender, Message(idSender: idSender, idReceiver: idReceiver, content: content);
idReceiver: idReceiver,
content: content);
MyApp.controller.sendMessage(messageToSend, idSender, idReceiver); MyApp.controller.sendMessage(messageToSend, idSender, idReceiver);
@ -176,14 +173,30 @@ class _ConversationPageState extends State<ConversationPage> {
color: const Color(0xFF141414), color: const Color(0xFF141414),
height: height * 0.92, height: height * 0.92,
width: double.infinity, width: double.infinity,
child: ListView.builder( child: Flexible(
child: StreamBuilder<List<Message>>(
stream: MyApp.controller.getMessage(
MyApp.controller.currentUser.usernameDafl,
receiver.usernameDafl),
builder: (BuildContext context,
AsyncSnapshot<List<Message>> snapshot) {
if (snapshot.hasData) {
List<Message> listMessage =
snapshot.data ?? List.from([]);
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) =>
messageWidget(listMessage[index]),
itemCount: listMessage.length,
reverse: true,
controller: listScrollController, controller: listScrollController,
physics: const BouncingScrollPhysics(), );
itemCount: messages.length, } else {
itemBuilder: (context, index) { return Center(child: Container());
return messages[index]; }
})), },
), ),
))),
bottomSheet: BottomAppBar( bottomSheet: BottomAppBar(
color: const Color(0xFF141414), color: const Color(0xFF141414),
child: Row( child: Row(
@ -225,7 +238,10 @@ class _ConversationPageState extends State<ConversationPage> {
onTap: isNull onTap: isNull
? null ? null
: () { : () {
sendMessage(messageTextField.text, MyApp.controller.currentUser.usernameDafl, receiver.usernameDafl); sendMessage(
messageTextField.text,
MyApp.controller.currentUser.usernameDafl,
receiver.usernameDafl);
if (listScrollController.hasClients) { if (listScrollController.hasClients) {
final position = final position =
listScrollController.position.maxScrollExtent; listScrollController.position.maxScrollExtent;

Loading…
Cancel
Save