login auth
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
org.gradle.jvmargs=-Xmx1536m -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8
|
||||||
|
org.gradle.parallel=false
|
||||||
|
org.gradle.workers.max=1
|
||||||
|
org.gradle.daemon=false
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
# This newDsl flag was added by the Flutter template
|
# This newDsl flag was added by the Flutter template
|
||||||
android.newDsl=false
|
android.newDsl=false
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ class ApiConstants {
|
|||||||
static const String resetPin = '$baseUrl/customer/reset-pin';
|
static const String resetPin = '$baseUrl/customer/reset-pin';
|
||||||
static const String logout = '$baseUrl/customer/logout';
|
static const String logout = '$baseUrl/customer/logout';
|
||||||
|
|
||||||
|
// ---- Email OTP (Replace Firebase) ----
|
||||||
|
static const String sendEmailOtp = '$baseUrl/customer/send-email-otp';
|
||||||
|
static const String verifyEmailOtp = '$baseUrl/customer/verify-email-otp';
|
||||||
|
|
||||||
// ---- Profile ----
|
// ---- Profile ----
|
||||||
static const String profile = '$baseUrl/customer/profile';
|
static const String profile = '$baseUrl/customer/profile';
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class _OtpScreenState extends State<OtpScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_startTimer();
|
_startTimer();
|
||||||
// Pre-fill demo OTP for the no-backend prototype.
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => _nodes[0].requestFocus());
|
WidgetsBinding.instance.addPostFrameCallback((_) => _nodes[0].requestFocus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,10 +147,10 @@ class _OtpScreenState extends State<OtpScreen> {
|
|||||||
height: 88,
|
height: 88,
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: AppColors.primaryFixed, shape: BoxShape.circle),
|
color: AppColors.primaryFixed, shape: BoxShape.circle),
|
||||||
child: const Icon(Icons.sms_rounded, size: 40, color: AppColors.primary),
|
child: const Icon(Icons.mark_email_read_rounded, size: 40, color: AppColors.primary),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
Text('Verify your number',
|
Text('Verify your email',
|
||||||
textAlign: TextAlign.center, style: AppTheme.headlineLg),
|
textAlign: TextAlign.center, style: AppTheme.headlineLg),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text.rich(
|
Text.rich(
|
||||||
@@ -160,7 +159,7 @@ class _OtpScreenState extends State<OtpScreen> {
|
|||||||
children: [
|
children: [
|
||||||
const TextSpan(text: 'We sent a 6-digit code to '),
|
const TextSpan(text: 'We sent a 6-digit code to '),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: '+91 ${phone.isEmpty ? '98111 22334' : phone}',
|
text: context.read<AppState>().pendingEmail ?? 'your email',
|
||||||
style: AppTheme.labelMd,
|
style: AppTheme.labelMd,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -194,9 +193,6 @@ class _OtpScreenState extends State<OtpScreen> {
|
|||||||
loading: _loading,
|
loading: _loading,
|
||||||
onPressed: filled ? _verify : null,
|
onPressed: filled ? _verify : null,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
|
||||||
Text('Tip: enter any 6 digits to continue',
|
|
||||||
style: AppTheme.caption.copyWith(color: AppColors.outline)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -134,73 +134,43 @@ class AppState extends ChangeNotifier {
|
|||||||
pendingEmail = email;
|
pendingEmail = email;
|
||||||
isResettingPin = resetPin;
|
isResettingPin = resetPin;
|
||||||
|
|
||||||
try {
|
if (email == null || email.isEmpty) {
|
||||||
if (kIsWeb) {
|
onError('Email address is required for verification.');
|
||||||
debugPrint('⚠️ RUNNING ON WEB: Bypassing Firebase OTP (Mocking success)');
|
return;
|
||||||
Future.delayed(const Duration(seconds: 1), () {
|
}
|
||||||
verificationId = 'mock_verification_id_$fullPhone';
|
|
||||||
onSuccess();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debugPrint('====================================');
|
try {
|
||||||
debugPrint('🚀 INITIATING LIVE FIREBASE OTP FOR: $fullPhone');
|
final res = await http.post(
|
||||||
await FirebaseAuth.instance.verifyPhoneNumber(
|
Uri.parse(ApiConstants.sendEmailOtp),
|
||||||
phoneNumber: fullPhone,
|
headers: {'Content-Type': 'application/json'},
|
||||||
verificationCompleted: (PhoneAuthCredential credential) async {
|
body: jsonEncode({"email": email, "phone": fullPhone}),
|
||||||
debugPrint('✅ VERIFICATION COMPLETED AUTOMATICALLY');
|
|
||||||
try {
|
|
||||||
await FirebaseAuth.instance.signInWithCredential(credential);
|
|
||||||
} catch (e) {
|
|
||||||
debugPrint('❌ ERROR SIGNING IN: $e');
|
|
||||||
onError(e.toString());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
verificationFailed: (FirebaseAuthException e) {
|
|
||||||
debugPrint('❌ VERIFICATION FAILED: ${e.code} - ${e.message}');
|
|
||||||
onError(e.message ?? 'Verification failed');
|
|
||||||
},
|
|
||||||
codeSent: (String vId, int? resendToken) {
|
|
||||||
debugPrint('✅ CODE SUCCESSFULLY SENT. Verification ID: $vId');
|
|
||||||
verificationId = vId;
|
|
||||||
onSuccess();
|
|
||||||
},
|
|
||||||
codeAutoRetrievalTimeout: (String vId) {
|
|
||||||
debugPrint('⚠️ AUTO RETRIEVAL TIMEOUT. Verification ID: $vId');
|
|
||||||
verificationId = vId;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
|
onSuccess();
|
||||||
|
} else {
|
||||||
|
final body = jsonDecode(res.body);
|
||||||
|
onError(body['message'] ?? 'Failed to send verification code.');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('💥 FIREBASE OTP CRASHED COMPLETELY: $e');
|
onError('Error: $e');
|
||||||
onError('Firebase OTP Error: $e');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> verifyOtp(String smsCode, {required Function onSuccess, required Function(String) onError}) async {
|
Future<void> verifyOtp(String smsCode, {required Function onSuccess, required Function(String) onError}) async {
|
||||||
if (verificationId == null) {
|
|
||||||
onError('Verification ID is missing. Please resend OTP.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (kIsWeb) {
|
final res = await http.post(
|
||||||
debugPrint('⚠️ RUNNING ON WEB: Bypassing Firebase OTP verification (Mocking success)');
|
Uri.parse(ApiConstants.verifyEmailOtp),
|
||||||
Future.delayed(const Duration(seconds: 1), () {
|
headers: {'Content-Type': 'application/json'},
|
||||||
if (smsCode.length == 6) {
|
body: jsonEncode({"email": pendingEmail, "otp": smsCode}),
|
||||||
onSuccess();
|
|
||||||
} else {
|
|
||||||
onError('Invalid mock OTP code (must be 6 digits).');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhoneAuthCredential credential = PhoneAuthProvider.credential(
|
|
||||||
verificationId: verificationId!,
|
|
||||||
smsCode: smsCode,
|
|
||||||
);
|
);
|
||||||
await FirebaseAuth.instance.signInWithCredential(credential);
|
|
||||||
onSuccess();
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
|
onSuccess();
|
||||||
|
} else {
|
||||||
|
final body = jsonDecode(res.body);
|
||||||
|
onError(body['message'] ?? 'Invalid verification code.');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
onError('Error: $e');
|
onError('Error: $e');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user