proxybuy-flutter/lib/screens/auth/bloc/auth_bloc.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()}"));
}
}
}