Compare commits

...

6 Commits

Author SHA1 Message Date
Audric SABATIER bd1e2efa2e ADD : Discplay messages in the views
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 27e970a3b9 ADD : controller call Firestore database accesser
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 77de0b8384 ADD : methods to get messages from Firestore
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 974b046f72 ADD : send message to firestore database with an unique chatID
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 308bfd95cd ADD : modify class message to have hashMap
continuous-integration/drone/push Build is failing Details
2 years ago
Audric SABATIER 32dd6c986c ADD : Firebase to project
continuous-integration/drone/push Build is passing Details
2 years ago

@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "943188299704",
"project_id": "daflmusic-b3b74",
"storage_bucket": "daflmusic-b3b74.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:943188299704:android:995199bd5229a330a9c94d",
"android_client_info": {
"package_name": "com.example.dafl_project_flutter"
}
},
"oauth_client": [
{
"client_id": "943188299704-qp12a784hmdo97v7qq78ekasgrfkmo52.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBehHyqsXbBm1I7fBSG2bPOQvpDX-8Rm7I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "943188299704-qp12a784hmdo97v7qq78ekasgrfkmo52.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>943188299704-h4035qno57lll2km151rdh3bgbb22vk7.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.943188299704-h4035qno57lll2km151rdh3bgbb22vk7</string>
<key>API_KEY</key>
<string>AIzaSyCnQnCeu7gdc1_uIOxXVNQT1pG8xjD_tB8</string>
<key>GCM_SENDER_ID</key>
<string>943188299704</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.example.daflProjectFlutter</string>
<key>PROJECT_ID</key>
<string>daflmusic-b3b74</string>
<key>STORAGE_BUCKET</key>
<string>daflmusic-b3b74.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:943188299704:ios:bd6866b329aebb64a9c94d</string>
</dict>
</plist>

@ -0,0 +1,7 @@
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:943188299704:ios:bd6866b329aebb64a9c94d",
"FIREBASE_PROJECT_ID": "daflmusic-b3b74",
"GCM_SENDER_ID": "943188299704"
}

@ -1,4 +1,7 @@
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/firebase_services/message_database_services.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import '../persistence/database_loader.dart'; import '../persistence/database_loader.dart';
@ -13,6 +16,8 @@ class Controller {
static Saver saver = DatabaseSaver(); static Saver saver = DatabaseSaver();
static Loader loader = DatabaseLoader(); static Loader loader = DatabaseLoader();
static final Searcher _searcher = DatabaseSearcher(); static final Searcher _searcher = DatabaseSearcher();
final MessageDatabaseServices _messageAccess = MessageDatabaseServices();
final NotificationService _notificationService = NotificationService();
late BuildContext navigatorKey; late BuildContext navigatorKey;
@ -20,6 +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) {
_messageAccess.sendMessage(message, idSender, idReceiver);
}
Stream<List<Message>> getMessage(String idSender, String idReceiver) {
return _messageAccess.getMessage(idSender, idReceiver);
} }
void save(User userToSave) { void save(User userToSave) {

@ -0,0 +1,69 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyBehHyqsXbBm1I7fBSG2bPOQvpDX-8Rm7I',
appId: '1:943188299704:android:995199bd5229a330a9c94d',
messagingSenderId: '943188299704',
projectId: 'daflmusic-b3b74',
storageBucket: 'daflmusic-b3b74.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCnQnCeu7gdc1_uIOxXVNQT1pG8xjD_tB8',
appId: '1:943188299704:ios:bd6866b329aebb64a9c94d',
messagingSenderId: '943188299704',
projectId: 'daflmusic-b3b74',
storageBucket: 'daflmusic-b3b74.appspot.com',
iosClientId: '943188299704-h4035qno57lll2km151rdh3bgbb22vk7.apps.googleusercontent.com',
iosBundleId: 'com.example.daflProjectFlutter',
);
}

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

@ -1,8 +1,34 @@
import 'user.dart'; import 'user.dart';
class Message { class Message {
User sender; String idSender;
String idReceiver;
String content; String content;
Message(this.sender, this.content); Message({
required this.idSender,
required this.idReceiver,
required this.content,
});
Map<String, dynamic> toHashMap() {
return {
'idSender': idSender,
'idReceiver': idReceiver,
'content': content,
};
}
factory Message.fromMap(Map<String, dynamic> data) {
return Message(
idSender: data['idSender'],
idReceiver: data['idReceiver'],
content: data['content'],
);
}
@override
String toString() {
return "idSender : $idSender " + "Content : $content \n";
}
} }

@ -1,5 +1,5 @@
import 'dart:async'; import 'dart:async';
import '../../../position/location.dart'; import '../position/location.dart';
import '../exceptions/api_exception.dart'; import '../exceptions/api_exception.dart';
import '../main.dart'; import '../main.dart';
import 'music.dart'; import 'music.dart';
@ -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();

@ -12,21 +12,25 @@ class ConversationPage extends StatefulWidget {
} }
class _ConversationPageState extends State<ConversationPage> { class _ConversationPageState extends State<ConversationPage> {
User destinataire = User("test1", '1234'); User receiver = User("test1", '1234');
List<Widget> messages = []; List<Widget> messages = [];
bool isNull = true; bool isNull = true;
final messageTextField = TextEditingController(); final messageTextField = TextEditingController();
void sendMessage(String content) { void sendMessage(String content, String idSender, String idReceiver) {
Message messageToSend =
Message(idSender: idSender, idReceiver: idReceiver, content: content);
MyApp.controller.sendMessage(messageToSend, idSender, idReceiver);
setState(() { setState(() {
messages messages.add(messageWidget(messageToSend));
.add(messageWidget(Message(MyApp.controller.currentUser, content)));
}); });
} }
Widget messageWidget(Message message) { Widget messageWidget(Message message) {
if (message.sender != MyApp.controller.currentUser) { if (message.idSender != MyApp.controller.currentUser.usernameDafl) {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Container( child: Container(
@ -165,18 +169,34 @@ class _ConversationPageState extends State<ConversationPage> {
), ),
), ),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Container( child: Container(
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(
controller: listScrollController, child: StreamBuilder<List<Message>>(
physics: const BouncingScrollPhysics(), stream: MyApp.controller.getMessage(
itemCount: messages.length, MyApp.controller.currentUser.usernameDafl,
itemBuilder: (context, index) { receiver.usernameDafl),
return messages[index]; 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,
);
} else {
return Center(child: Container());
}
},
),
))),
bottomSheet: BottomAppBar( bottomSheet: BottomAppBar(
color: const Color(0xFF141414), color: const Color(0xFF141414),
child: Row( child: Row(
@ -218,7 +238,10 @@ class _ConversationPageState extends State<ConversationPage> {
onTap: isNull onTap: isNull
? null ? null
: () { : () {
sendMessage(messageTextField.text); 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;
@ -375,7 +398,7 @@ class _ConversationPageState extends State<ConversationPage> {
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
MyApp.controller.sendEmail(MyApp.controller.currentUser, MyApp.controller.sendEmail(MyApp.controller.currentUser,
destinataire, currentValue, messageTextField.text); receiver, currentValue, messageTextField.text);
Navigator.pop(context); Navigator.pop(context);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart'; import 'package:page_transition/page_transition.dart';
import 'p_conversation.dart'; import 'p_conversation.dart';
class MessagesWidget extends StatefulWidget { class MessagesWidget extends StatefulWidget {

@ -1,6 +1,13 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.9"
animations: animations:
dependency: "direct main" dependency: "direct main"
description: description:
@ -71,6 +78,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
cloud_firestore:
dependency: "direct main"
description:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "5.9.0"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -127,6 +155,48 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.5.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
version: "14.1.1"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.7"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.7"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter

@ -29,6 +29,9 @@ dependencies:
home_indicator: ^2.0.2 home_indicator: ^2.0.2
geolocator: ^9.0.2 geolocator: ^9.0.2
flutter_styled_toast: ^2.1.3 flutter_styled_toast: ^2.1.3
firebase_core: ^2.3.0
firebase_messaging: ^14.1.1
cloud_firestore: ^4.1.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save