import 'dart:async'; import 'package:flutter/foundation.dart' show debugPrint, kDebugMode; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import '../constants.dart'; import '../main.dart'; import '../utils/helper_dialogs.dart'; import 'user_service.dart'; class SwipeStreamService { final FirebaseFirestore _firestore = FirebaseFirestore.instance; final List _matchesInDB = []; StreamSubscription>? _subscription; late String userId; late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; late bool matchesRead = false; // Singleton instance static final SwipeStreamService _instance = SwipeStreamService._internal(); // Private constructor SwipeStreamService._internal(); // Factory constructor factory SwipeStreamService() { return _instance; } // Initialization method void initialize(String userId, FlutterLocalNotificationsPlugin plugin) { _instance.userId = userId; _instance.flutterLocalNotificationsPlugin = plugin; // Reset old data _matchesInDB.clear(); matchesRead = false; } Stream> get swipesStream { return _firestore .collection(Constants.dbCollectionUsers) .doc(userId) .collection(Constants.dbCollectionMatches) .snapshots() .map((snapshot) => snapshot.docs); } void _showNotification(String swipeId) async { String matchName = await UserService.getUserName(swipeId); const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails( 'new_matches_channel_id', 'new_match_info', channelShowBadge: true, visibility: NotificationVisibility.private, importance: Importance.max, priority: Priority.high, showWhen: true); const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); await flutterLocalNotificationsPlugin.show(0, 'New Match', 'You have a new match with $matchName', platformChannelSpecifics); } void listenToSwipes() { _subscription = swipesStream.listen( (swipes) async { List userNames = []; String tempUser = ''; if (!matchesRead) { for (var swipe in swipes) { debugPrint('Init Match Notify --> ${swipe.id}'); _matchesInDB.add(swipe.id); tempUser = await UserService.getUserName(swipe.id); userNames.add('INIT $tempUser'); } if (kDebugMode) { showErrorSnackBar( navigatorKey.currentContext!, userNames.join(', '), ); } matchesRead = true; } else { for (var swipe in swipes) { tempUser = await UserService.getUserName(swipe.id); if (!_matchesInDB.contains(swipe.id)) { userNames.add('NEW! $tempUser'); debugPrint('NEW Match Notify --> ${swipe.id}'); _matchesInDB.add(swipe.id); _showNotification(swipe.id); } else { userNames.add('OLD $tempUser'); debugPrint('Old Match Notify --> ${swipe.id}'); } } if (kDebugMode) { showErrorSnackBar( navigatorKey.currentContext!, userNames.join(', '), ); } } }, ); } void stopListening() { _subscription?.cancel(); _subscription = null; } void addUser(String userId) { if (!_matchesInDB.contains(userId)) { debugPrint('Notify: SKIP Match Notify for --> $userId'); _matchesInDB.add(userId); } } }