Fix auth: auto-create customer, display name flow, OTP auto-verify
- Backend: getOrCreateCustomer with phone fallback for re-login - Backend: PATCH /api/client/auth/profile for display name update - Client app: AuthNeedsDisplayNameData state + SetDisplayNameScreen - Client app: ApiClient.patch method - Both apps: handle verificationCompleted for auto-verify (test numbers) - Both apps: skip credential sign-in if already auto-verified - Remove debug prints from mitra auth + OTP screens - Fix ChatRequestNotifier.startListening skips when accepting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,11 @@ class AuthForceRegisterData extends AuthData {
|
||||
const AuthForceRegisterData({required this.customerId, required this.displayName});
|
||||
}
|
||||
|
||||
class AuthNeedsDisplayNameData extends AuthData {
|
||||
final Map<String, dynamic> profile;
|
||||
const AuthNeedsDisplayNameData(this.profile);
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class Auth extends _$Auth {
|
||||
FirebaseAuth get _auth => FirebaseAuth.instance;
|
||||
@@ -132,7 +137,11 @@ class Auth extends _$Auth {
|
||||
final completer = Completer<void>();
|
||||
await _auth.verifyPhoneNumber(
|
||||
phoneNumber: phone,
|
||||
verificationCompleted: (_) {
|
||||
verificationCompleted: (credential) async {
|
||||
try {
|
||||
await _auth.signInWithCredential(credential);
|
||||
state = AsyncData(await _verifyAndReturn());
|
||||
} catch (_) {}
|
||||
if (!completer.isCompleted) completer.complete();
|
||||
},
|
||||
verificationFailed: (e) {
|
||||
@@ -153,11 +162,14 @@ class Auth extends _$Auth {
|
||||
Future<void> verifyOtp(String verificationId, String smsCode) async {
|
||||
state = const AsyncLoading();
|
||||
try {
|
||||
final credential = PhoneAuthProvider.credential(
|
||||
verificationId: verificationId,
|
||||
smsCode: smsCode,
|
||||
);
|
||||
await _auth.signInWithCredential(credential);
|
||||
// If already signed in via auto-verification, skip credential sign-in
|
||||
if (_auth.currentUser == null || _auth.currentUser!.isAnonymous) {
|
||||
final credential = PhoneAuthProvider.credential(
|
||||
verificationId: verificationId,
|
||||
smsCode: smsCode,
|
||||
);
|
||||
await _auth.signInWithCredential(credential);
|
||||
}
|
||||
state = AsyncData(await _verifyAndReturn());
|
||||
} catch (e) {
|
||||
state = AsyncError('Invalid OTP. Please try again.', StackTrace.current);
|
||||
@@ -191,8 +203,24 @@ class Auth extends _$Auth {
|
||||
state = const AsyncData(AuthInitialData());
|
||||
}
|
||||
|
||||
Future<void> setDisplayName(String displayName) async {
|
||||
state = const AsyncLoading();
|
||||
try {
|
||||
final response = await _apiClient.patch('/api/client/auth/profile', data: {
|
||||
'display_name': displayName,
|
||||
});
|
||||
state = AsyncData(AuthAuthenticatedData(response['data'] as Map<String, dynamic>));
|
||||
} catch (e) {
|
||||
state = AsyncError('Gagal menyimpan nama. Coba lagi.', StackTrace.current);
|
||||
}
|
||||
}
|
||||
|
||||
Future<AuthData> _verifyAndReturn() async {
|
||||
final response = await _apiClient.post('/api/client/auth/verify');
|
||||
return AuthAuthenticatedData(response['data'] as Map<String, dynamic>);
|
||||
final profile = response['data'] as Map<String, dynamic>;
|
||||
if (profile['display_name'] == null || (profile['display_name'] as String).isEmpty) {
|
||||
return AuthNeedsDisplayNameData(profile);
|
||||
}
|
||||
return AuthAuthenticatedData(profile);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user