import 'dart:async'; import 'serialization_util.dart'; import '../backend.dart'; import '../../flutter_flow/flutter_flow_theme.dart'; import '../../flutter_flow/flutter_flow_util.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; final _handledMessageIds = {}; class PushNotificationsHandler extends StatefulWidget { const PushNotificationsHandler({super.key, required this.child}); final Widget child; @override _PushNotificationsHandlerState createState() => _PushNotificationsHandlerState(); } class _PushNotificationsHandlerState extends State { bool _loading = false; Future handleOpenedPushNotification() async { if (isWeb) { return; } final notification = await FirebaseMessaging.instance.getInitialMessage(); if (notification != null) { await _handlePushNotification(notification); } FirebaseMessaging.onMessageOpenedApp.listen(_handlePushNotification); } Future _handlePushNotification(RemoteMessage message) async { if (_handledMessageIds.contains(message.messageId)) { return; } _handledMessageIds.add(message.messageId); if (mounted) { setState(() => _loading = true); } try { final initialPageName = message.data['initialPageName'] as String; final initialParameterData = getInitialParameterData(message.data); final parametersBuilder = parametersBuilderMap[initialPageName]; if (parametersBuilder != null) { final parameterData = await parametersBuilder(initialParameterData); context.pushNamed( initialPageName, pathParameters: parameterData.pathParameters, extra: parameterData.extra, ); } } catch (e) { print('Error: $e'); } finally { if (mounted) { setState(() => _loading = false); } } } @override void initState() { super.initState(); handleOpenedPushNotification(); } @override Widget build(BuildContext context) => _loading ? Container( color: FlutterFlowTheme.of(context).primary, child: Image.asset( 'assets/images/logo.svg', fit: BoxFit.cover, ), ) : widget.child; } class ParameterData { const ParameterData( {this.requiredParams = const {}, this.allParams = const {}}); final Map requiredParams; final Map allParams; Map get pathParameters => Map.fromEntries( requiredParams.entries .where((e) => e.value != null) .map((e) => MapEntry(e.key, e.value!)), ); Map get extra => Map.fromEntries( allParams.entries.where((e) => e.value != null), ); static Future Function(Map) none() => (data) async => const ParameterData(); } final parametersBuilderMap = Function(Map)>{ 'LoginPage': (data) async => ParameterData( allParams: { 'device': getParameter(data, 'device'), }, ), 'ForgotPasswordPage': ParameterData.none(), 'homePage': (data) async => ParameterData( allParams: { 'userUUID': getParameter(data, 'userUUID'), 'devUUID': getParameter(data, 'devUUID'), }, ), 'RegisterPage': ParameterData.none(), 'WelcomePage': ParameterData.none(), 'registerVisitorPage': (data) async => ParameterData( allParams: { 'userUUID': getParameter(data, 'userUUID'), 'devUUID': getParameter(data, 'devUUID'), }, ), 'scheduleCompleteVisitPage': (data) async => ParameterData( allParams: { 'visitorStrList': getParameter(data, 'visitorStrList'), 'visitStartDateStr': getParameter(data, 'visitStartDateStr'), 'visitEndDateStr': getParameter(data, 'visitEndDateStr'), 'visitReasonStr': getParameter(data, 'visitReasonStr'), 'visitLevelStr': getParameter(data, 'visitLevelStr'), 'visitTempBol': getParameter(data, 'visitTempBol'), 'visitObsStr': getParameter(data, 'visitObsStr'), }, ), 'scheduleProvisionalVisitPage': ParameterData.none(), }; Map getInitialParameterData(Map data) { try { final parameterDataStr = data['parameterData']; if (parameterDataStr == null || parameterDataStr is! String || parameterDataStr.isEmpty) { return {}; } return jsonDecode(parameterDataStr) as Map; } catch (e) { print('Error parsing parameter data: $e'); return {}; } }