149 lines
4.5 KiB
Dart
149 lines
4.5 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:google_sign_in/google_sign_in.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
|
|
part 'auth_event.dart';
|
|
part 'auth_state.dart';
|
|
|
|
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
|
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
|
|
String? _verificationId;
|
|
|
|
AuthBloc() : super(AuthInitial()) {
|
|
on<SendOTPEvent>(_onSendOTP);
|
|
on<VerifyOTPEvent>(_onVerifyOTP);
|
|
on<SignInWithGoogleEvent>(_onSignInWithGoogle);
|
|
on<SignOutEvent>(_onSignOut);
|
|
}
|
|
|
|
Future<void> _onSendOTP(SendOTPEvent event, Emitter<AuthState> emit) async {
|
|
emit(AuthLoading());
|
|
final completer = Completer<void>();
|
|
try {
|
|
await _firebaseAuth.verifyPhoneNumber(
|
|
phoneNumber: event.phoneNumber,
|
|
verificationCompleted: (PhoneAuthCredential credential) async {
|
|
debugPrint("✅ Verification Completed (Auto-retrieval)");
|
|
await _firebaseAuth.signInWithCredential(credential);
|
|
if (!completer.isCompleted) {
|
|
emit(OTPVerified());
|
|
completer.complete();
|
|
}
|
|
},
|
|
verificationFailed: (FirebaseAuthException e) {
|
|
debugPrint("❌ Verification Failed: ${e.message}");
|
|
if (!completer.isCompleted) {
|
|
emit(AuthError(e.message ?? 'Verification Failed'));
|
|
completer.complete();
|
|
}
|
|
},
|
|
codeSent: (String verificationId, int? resendToken) {
|
|
debugPrint("📬 Code Sent! Verification ID: $verificationId");
|
|
_verificationId = verificationId;
|
|
if (!completer.isCompleted) {
|
|
emit(AuthCodeSent(
|
|
phoneNumber: event.phoneNumber,
|
|
));
|
|
completer.complete();
|
|
}
|
|
},
|
|
codeAutoRetrievalTimeout: (String verificationId) {
|
|
debugPrint("⌛️ Code Auto-retrieval Timeout.");
|
|
},
|
|
);
|
|
await completer.future;
|
|
} catch (e) {
|
|
debugPrint("⛔️ General Error in _onSendOTP: ${e.toString()}");
|
|
if (!completer.isCompleted) {
|
|
emit(AuthError(e.toString()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// ... بقیه کد بدون تغییر ...
|
|
Future<void> _onVerifyOTP(VerifyOTPEvent event, Emitter<AuthState> emit) async {
|
|
emit(AuthLoading());
|
|
try {
|
|
if (_verificationId != null) {
|
|
final credential = PhoneAuthProvider.credential(
|
|
verificationId: _verificationId!,
|
|
smsCode: event.otpCode,
|
|
);
|
|
|
|
await _firebaseAuth.signInWithCredential(credential);
|
|
emit(OTPVerified());
|
|
} else {
|
|
emit(AuthError("Verification ID not found. Please try again."));
|
|
}
|
|
} on FirebaseAuthException catch (e) {
|
|
if (e.code == 'invalid-verification-code') {
|
|
emit(AuthError('The code entered is incorrect. Please try again.'));
|
|
} else {
|
|
emit(AuthError(e.message ?? 'An error occurred'));
|
|
}
|
|
} catch (e) {
|
|
emit(AuthError(e.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> _onSignInWithGoogle(
|
|
SignInWithGoogleEvent event,
|
|
Emitter<AuthState> emit,
|
|
) async {
|
|
emit(AuthLoading());
|
|
try {
|
|
final GoogleSignIn googleSignIn = GoogleSignIn(
|
|
scopes: ['email'],
|
|
);
|
|
|
|
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
|
|
|
|
if (googleUser == null) {
|
|
emit(AuthInitial());
|
|
return;
|
|
}
|
|
|
|
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
|
|
|
final credential = GoogleAuthProvider.credential(
|
|
accessToken: googleAuth.accessToken,
|
|
idToken: googleAuth.idToken,
|
|
);
|
|
|
|
final UserCredential userCredential =
|
|
await _firebaseAuth.signInWithCredential(credential);
|
|
|
|
if (userCredential.user != null) {
|
|
emit(GoogleSignInSuccess());
|
|
} else {
|
|
emit(AuthError("Error signing in with Google"));
|
|
}
|
|
|
|
} catch (e) {
|
|
emit(AuthError("Error signing in with Google: ${e.toString()}"));
|
|
}
|
|
}
|
|
|
|
Future<void> _onSignOut(SignOutEvent event, Emitter<AuthState> emit) async {
|
|
emit(AuthLoading());
|
|
try {
|
|
debugPrint('🚪 Starting logout process...');
|
|
|
|
await GoogleSignIn().signOut();
|
|
debugPrint('✅ Google SignOut completed');
|
|
|
|
await _firebaseAuth.signOut();
|
|
debugPrint('✅ Firebase SignOut completed');
|
|
|
|
emit(AuthInitial());
|
|
debugPrint('✅ AuthInitial state emitted');
|
|
|
|
} catch (e) {
|
|
debugPrint('❌ Error in logout: $e');
|
|
emit(AuthError("Error signing out: ${e.toString()}"));
|
|
}
|
|
}
|
|
|
|
} |