testa ai pa nois

This commit is contained in:
Jonatas Antunes Messias 2024-06-19 16:36:40 -03:00
parent eacc6e541d
commit 44a8f84477
16 changed files with 311 additions and 160 deletions

File diff suppressed because one or more lines are too long

View File

@ -44,6 +44,11 @@
</intent-filter>
<!-- Deep linking -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_fre_black" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,69 +1,38 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:rxdart/rxdart.dart';
import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart';
import 'dart:io' show Platform;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
class PushNotificationService {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
Function(BuildContext)? onNotificationClick;
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final Subject<RemoteMessage> _onMessage = BehaviorSubject<RemoteMessage>();
final BehaviorSubject<BuildContext> _context =
BehaviorSubject<BuildContext>();
/// Inicializa o serviço de notificação push.
Future<void> initialize() async {
FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
PushNotificationService() {
_initializeLocalNotifications(_context);
}
Future<void> initialize(BuildContext context) async {
_context.add(context);
await _requestPermissions();
_configureLocalNotification(_flutterLocalNotificationsPlugin);
_listenToForegroundMessages(_flutterLocalNotificationsPlugin);
_handleMessageTap();
_listenToForegroundMessages(context);
_listenToBackgroundMessages();
_listenToNotificationClicks(context);
await _updateDeviceToken();
}
void showCustomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return const VisitRequestTemplateComponentWidget(
name: '', // Supondo que esses valores serão extraídos da mensagem
image: '',
message: '',
reason: '',
);
},
);
}
void _configureLocalNotification(
FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) {
var initializationSettingsAndroid =
const AndroidInitializationSettings('mipmap/ic_launcher');
var initializationSettingsIOS = const DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
_flutterLocalNotificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse: (response) async {
debugPrint('Notification tapped!');
});
}
/// Solicita permissões ao usuário para iOS.
Future<void> _requestPermissions() async {
NotificationSettings settings = await _firebaseMessaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
debugPrint('User granted permission');
} else {
@ -71,88 +40,182 @@ class PushNotificationService {
}
}
void _listenToForegroundMessages(
FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
debugPrint('Got a message whilst in the foreground!');
debugPrint('Message data: ${message.data}');
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
_flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
const NotificationDetails(
android: AndroidNotificationDetails(
'your_channel_id',
'Your Channel Name',
channelDescription: 'Your Channel Description',
importance: Importance.max,
priority: Priority.high,
icon: 'mipmap/ic_launcher',
),
Map<String, dynamic> validJsonFromString(String? string) {
// Switch(string != null || string.isNotEmpty) {
// case true:
// debugPrint()
// break;
// }
String stringValidate = string!
.replaceAllMapped(RegExp(r'(\w+):'),
(match) => '"${match[1]}":') // Enclose keys in double quotes
.replaceAllMapped(RegExp(r':\s*(\w+)'), (match) => ': "${match[1]}"');
Map<String, dynamic> json = jsonDecode(stringValidate);
return json;
}
void _initializeLocalNotifications(
BehaviorSubject<BuildContext> context) async {
while (context.valueOrNull == null) {
await Future.delayed(Duration(milliseconds: 100));
}
var initializationSettingsAndroid =
AndroidInitializationSettings('mipmap/ic_fre_black');
var initializationSettingsIOS = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
_flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) async {
debugPrint('Response payload:${response.payload}');
if (response.payload != null) {
// Preprocess the payload to ensure it's in a valid JSON format
String validJsonPayload = response.payload!
.replaceAllMapped(RegExp(r'(\w+):'),
(match) => '"${match[1]}":') // Enclose keys in double quotes
.replaceAllMapped(
RegExp(r':\s*(\w+)'),
(match) =>
': "${match[1]}"'); // Enclose string values in double quotes
try {
Map<String, dynamic> message = jsonDecode(validJsonPayload);
debugPrint('Notification payload: $message');
_handleNotificationClick(message);
} catch (e) {
debugPrint('Error decoding notification payload: $e');
}
}
},
);
_createNotificationChannel();
}
void _createNotificationChannel() {
_flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(
AndroidNotificationChannel(
'channelID',
'channelName',
description: 'Channel Description',
importance: Importance.max,
),
);
}
}
void _listenToForegroundMessages(BuildContext context) {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
debugPrint('Got a message whilst in the foreground!');
debugPrint('Message data: ${message.toMap()}');
_onMessage.add(message);
_showNotification(message);
});
}
/// Configura a ação ao tocar na notificação.
void _handleMessageTap() {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint('Message clicked!');
// Implementar ação ao tocar na notificação
});
}
/// Configura o ouvinte para mensagens em segundo plano.
void _listenToBackgroundMessages() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
/// Atualiza o token do dispositivo e envia para o servidor, se necessário.
void _listenToNotificationClicks(BuildContext context) {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint('Notification clicked!');
_onMessage.add(message);
NotificationHandler().handleMessage(message.data, context);
});
}
Future<void> _updateDeviceToken() async {
String? token = await _firebaseMessaging.getToken();
debugPrint('Push Messaging token: $token');
// Enviar token para o servidor
// Send token to your server if required
}
void _showNotification(RemoteMessage message) async {
var androidDetails = AndroidNotificationDetails(
'channelID',
'channelName',
channelDescription: 'Channel Description',
importance: Importance.max,
priority: Priority.high,
);
var iOSDetails = DarwinNotificationDetails();
var generalNotificationDetails =
NotificationDetails(android: androidDetails, iOS: iOSDetails);
await _flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification?.title,
message.notification?.body,
generalNotificationDetails,
payload: message.data.toString(),
);
}
_handleNotificationClick(Map<String, dynamic> payload) {
switch (payload.isNotEmpty) {
case true:
// Print the 'data' property
debugPrint('Notification payload: $payload');
// Handle the message data as needed
NotificationHandler().handleMessage(payload, _context.value);
// Access the 'data' property of 'RemoteMessage'
case false:
debugPrint('Notification payload is empty');
// Handle the message notification as needed
break;
}
}
static Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
debugPrint('Handling a background message: ${message.messageId}');
}
}
/// Manipula mensagens recebidas em segundo plano.
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
debugPrint('Handling a background message: ${message.messageId}');
}
class NotificationHandler {
void handleMessage(Map<String, dynamic> message, BuildContext context) {
debugPrint('Notification Received!');
message.forEach((key, value) {
debugPrint('$key: $value');
});
void _handleNotificationTap(
NotificationResponse response, BuildContext context) {
// Implementação para lidar com o toque na notificação
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return const VisitRequestTemplateComponentWidget(
name: '', // Supondo que esses valores serão extraídos da mensagem
image: '',
message: '',
reason: '',
);
},
);
}
switch (message['type']) {
case 'visit_request':
_showVisitRequestDialog(message, context);
break;
case 'visit_response':
debugPrint('visit_response');
break;
default:
debugPrint('Notification type not recognized');
}
}
void _handleMessageOpenedApp(RemoteMessage message, BuildContext context) {
// Mostra um modal ao invés de navegar para uma nova página
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return const VisitRequestTemplateComponentWidget(
name: '', // Supondo que esses valores serão extraídos da mensagem
image: '',
message: '',
reason: '',
);
},
);
void _showVisitRequestDialog(
Map<String, dynamic> message, BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
child: VisitRequestTemplateComponentWidget(
name: message['nome'] ?? 'Unknown',
reason: message['motivo'] ?? 'Unknown',
message: message['mensagem'] ?? 'Unknown',
document: message['documento'] ?? 'Unknown',
),
);
},
);
}
}

View File

@ -0,0 +1,90 @@
// import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
// import 'package:flutter/material.dart';
// import 'package:rxdart/rxdart.dart';
// class NotificationHandler {
// // Criar BehaviorSubjects para mensagens em primeiro plano e mensagens que abriram o app
// final BehaviorSubject<RemoteMessage> _onMessage =
// BehaviorSubject<RemoteMessage>();
// final BehaviorSubject<RemoteMessage> _onMessageOpenedApp =
// BehaviorSubject<RemoteMessage>();
// // Inicializar listeners no construtor
// NotificationHandler() {
// initializeListeners();
// }
// void initializeListeners() async {
// // Listener para mensagens em primeiro plano
// // FirebaseMessaging.onMessage.listen((message) {
// // _onMessage.add(message); // Adicionar mensagem ao stream
// // });
// RemoteMessage? initialMessage =
// await FirebaseMessaging.instance.getInitialMessage();
// if (initialMessage != null) _onMessage.add(initialMessage);
// // Listener para mensagens que abriram o app
// FirebaseMessaging.onMessageOpenedApp.listen((message) {
// _onMessageOpenedApp.add(message); // Adicionar mensagem ao stream
// });
// }
// void openedAppVisitRequestNotification(
// RemoteMessage message, BuildContext context) {
// debugPrint('openedAppVisitRequestNotification');
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return Dialog(
// backgroundColor:
// Colors.transparent, // Faz o fundo do Dialog ser transparente
// child: VisitRequestTemplateComponentWidget(
// name: message.data['nome'] ?? 'blabla',
// reason: message.data['motivo'] ?? 'blabla',
// message: message.data['mensagem'] ?? 'blabla',
// document: message.data['document']),
// );
// });
// }
// // Método para tratar mensagens recebidas
// void handleMessage(RemoteMessage message, BuildContext context) {
// debugPrint('Notification Received!');
// message.data.forEach((key, value) {
// debugPrint('$key: $value');
// });
// switch (message.data['type']) {
// case 'visit_request':
// openedAppVisitRequestNotification(message, context);
// break;
// case '':
// break;
// default:
// debugPrint('Notification type not recognized');
// }
// }
// // Ouvir streams
// void listenToNotifications(BuildContext context) {
// _onMessage.listen((message) {
// handleMessage(message, context);
// });
// _onMessageOpenedApp.listen((message) {
// handleMessage(message, context);
// });
// }
// // Dispor streams
// void dispose() {
// _onMessage.close();
// _onMessageOpenedApp.close();
// }
// }

View File

@ -4,6 +4,7 @@ import '/flutter_flow/flutter_flow_util.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'visit_request_template_component_model.dart';
export 'visit_request_template_component_model.dart';
@ -13,13 +14,13 @@ class VisitRequestTemplateComponentWidget extends StatefulWidget {
required this.name,
required this.reason,
required this.message,
required this.image,
required this.document,
});
final String? name;
final String? reason;
final String? message;
final String? image;
final String? document;
@override
State<VisitRequestTemplateComponentWidget> createState() =>
@ -63,6 +64,8 @@ class _VisitRequestTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
return Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Padding(
@ -96,7 +99,10 @@ class _VisitRequestTemplateComponentWidgetState
child: CachedNetworkImage(
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: widget.image!,
imageUrl: valueOrDefault<String>(
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.document}&tipo=E',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
fit: BoxFit.cover,
),
),
@ -447,7 +453,7 @@ class _VisitRequestTemplateComponentWidgetState
buttonSize: 40.0,
fillColor: FlutterFlowTheme.of(context).error,
icon: Icon(
Icons.add,
Icons.close,
color: FlutterFlowTheme.of(context).primaryBackground,
size: 24.0,
),

View File

@ -33,8 +33,6 @@ Future<void> initializeApp() async {
await appState.initializePersistedState();
GoRouter.optionURLReflectsImperativeAPIs = true;
usePathUrlStrategy();
final pushNotificationService = PushNotificationService();
await pushNotificationService.initialize();
}
class MyApp extends StatefulWidget {

View File

@ -1,5 +1,6 @@
// import 'package:f_r_e_hub/backend/push_notification/pushNotification.dart';
import 'package:f_r_e_hub/backend/push_notification/pushNotificationService.dart';
import 'package:f_r_e_hub/backend/push_notification/tapNotifcationActivity.dart';
import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
@ -35,46 +36,33 @@ class _HomePageWidgetState extends State<HomePageWidget> {
super.initState();
_model = createModel(context, () => HomePageModel());
// PushNotificationService().onNotificationClick = (context) {
// showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// builder: (BuildContext context) {
// return const VisitRequestTemplateComponentWidget(
// name: '', // Supondo que esses valores serão extraídos da mensagem
// image: '',
// message: '',
// reason: '',
// );
// },
// );
// };
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
FirebaseMessaging.onMessageOpenedApp.listen((message) {
debugPrint('onMessageOpenedApp Test');
debugPrint('name: ${message.data['nome']}');
debugPrint('reason: ${message.data['motivo']}');
debugPrint('message: ${message.data['mensagem']}');
debugPrint('image: ${message.data['imagem']}');
// final pushNotificationService = PushNotificationService();
// await pushNotificationService.initialize(context);
// NotificationHandler().listenToNotifications(context);
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor:
Colors.transparent, // Faz o fundo do Dialog ser transparente
child: VisitRequestTemplateComponentWidget(
name: message.data['nome'] ?? 'Nome Exemplo',
reason: message.data['motivo'] ?? 'Motivo Exemplo',
message: message.data['mensagem'] ?? 'Mensagem Exemplo',
image: 'URL da Imagem',
),
);
},
);
});
// Inicializa o serviço de notificação
await PushNotificationService().initialize(context);
// Opcional: Defina ações específicas quando uma notificação é recebida
// PushNotificationService().onMessage.listen((message) {
// // Implemente sua lógica aqui, por exemplo, navegar para uma nova página
// // ou mostrar um diálogo com a mensagem da notificação
// showDialog(
// context: context,
// builder: (context) => AlertDialog(
// title: Text("Notificação Recebida"),
// content: Text(message),
// actions: [
// TextButton(
// onPressed: () => Navigator.of(context).pop(),
// child: Text("OK"),
// ),
// ],
// ),
// );
// });
// });
if (FFAppState().cliUUID == '') {
showModalBottomSheet(

View File

@ -902,7 +902,7 @@ packages:
source: hosted
version: "0.2.0"
rxdart:
dependency: transitive
dependency: "direct main"
description:
name: rxdart
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"

View File

@ -29,6 +29,7 @@ dependencies:
cached_network_image: 3.3.1
firebase_core: 3.1.0
webview_flutter: ^4.8.0
rxdart: ^0.27.7
collection: 1.18.0
crop_your_image: 1.1.0
csv: 6.0.0