import 'dart:async'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/foundation.dart'; class OtpService { final FirebaseAuth _auth = FirebaseAuth.instance; String? _verificationId; int? _resendToken; /// Invia l'SMS al numero di telefono (deve avere il prefisso internazionale, es. +39). Future sendOtp({ required String phoneNumber, required Function(String verificationId) onCodeSent, required Function(FirebaseAuthException e) onVerificationFailed, required Function(PhoneAuthCredential credential) onVerificationCompleted, required Function(String verificationId) onCodeAutoRetrievalTimeout, }) async { // Normalizzazione numero (aggiunta +39 se manca) String normalizedPhone = phoneNumber.trim().replaceAll(' ', ''); if (!normalizedPhone.startsWith('+')) { if (normalizedPhone.startsWith('00')) { normalizedPhone = '+' + normalizedPhone.substring(2); } else { // Presumo Italia come default normalizedPhone = '+39' + normalizedPhone; } } debugPrint("Invio SMS a: $normalizedPhone"); await _auth.verifyPhoneNumber( phoneNumber: normalizedPhone, verificationCompleted: (PhoneAuthCredential credential) { // Solo su Android, a volte legge in automatico l'SMS onVerificationCompleted(credential); }, verificationFailed: (FirebaseAuthException e) { debugPrint("Verifica Fallita: ${e.message}"); onVerificationFailed(e); }, codeSent: (String verificationId, int? resendToken) { _verificationId = verificationId; _resendToken = resendToken; onCodeSent(verificationId); }, codeAutoRetrievalTimeout: (String verificationId) { _verificationId = verificationId; onCodeAutoRetrievalTimeout(verificationId); }, forceResendingToken: _resendToken, timeout: const Duration(seconds: 60), ); } /// Verifica il codice PIN (OTP) inserito dall'utente. /// Ritorna un UserCredential se la verifica ha successo, altrimenti lancia un'eccezione. Future verifyCode({required String verificationId, required String smsCode}) async { PhoneAuthCredential credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, ); // Firma e logga l'utente verificando l'OTP. return await _auth.signInWithCredential(credential); } /// Effettua il logout per ripulire lo stato se necessario (es. dopo l'invio del CID) Future signOut() async { await _auth.signOut(); } }