71 lines
2.6 KiB
Dart
71 lines
2.6 KiB
Dart
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<void> 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<UserCredential> 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<void> signOut() async {
|
|
await _auth.signOut();
|
|
}
|
|
}
|