import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_timezone/flutter_timezone.dart'; import '../../../core/firebase/firebase_providers.dart'; /// Registriert das Gerät für Push-Erinnerungen und hält die /// Erinnerungs-Einstellungen im Nutzer-Dokument aktuell. /// /// Abstrakte Basis, damit Tests eine No-Op-Variante einsetzen können. abstract class PushRegistrationService { Future registerDevice(User user); Future syncReminderTime(TimeOfDay time); } class FirebasePushRegistrationService implements PushRegistrationService { FirebasePushRegistrationService(this._firestore, this._auth); final FirebaseFirestore _firestore; final FirebaseAuth _auth; bool _tokenListenerAttached = false; @override Future registerDevice(User user) async { final messaging = FirebaseMessaging.instance; // Fragt beim ersten Mal die Push-Berechtigung ab (iOS-Dialog, // Android 13+ Systemdialog); danach ist der Aufruf ein No-Op. final settings = await messaging.requestPermission(); if (settings.authorizationStatus == AuthorizationStatus.denied) return; final token = await messaging.getToken(); if (token != null) { await _saveToken(user.uid, token); } if (!_tokenListenerAttached) { _tokenListenerAttached = true; messaging.onTokenRefresh.listen((newToken) { final current = _auth.currentUser; if (current != null) _saveToken(current.uid, newToken); }); } } Future _saveToken(String uid, String token) async { final timezone = await FlutterTimezone.getLocalTimezone(); await _firestore.collection('users').doc(uid).set({ 'fcmTokens': FieldValue.arrayUnion([token]), 'timezone': timezone, }, SetOptions(merge: true)); } @override Future syncReminderTime(TimeOfDay time) async { final user = _auth.currentUser; if (user == null) return; final formatted = '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}'; await _firestore.collection('users').doc(user.uid).set({ 'reminderTime': formatted, }, SetOptions(merge: true)); } } final pushRegistrationServiceProvider = Provider((ref) { return FirebasePushRegistrationService( ref.watch(firestoreProvider), ref.watch(firebaseAuthProvider), ); });