Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated sign in and sign up with firebase email and password #225

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions app/lib/app/data/repository/auth_repositoty_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,60 @@ final class AuthRepositoryImpl implements AuthRepository {
}
}

@override
Future<Either<UserEntity, Exception>> signUpWithEmail(
String email,
String password,
String languageCode,
Gender gender,
) async {
aidaiym marked this conversation as resolved.
Show resolved Hide resolved
try {
final res = await remoteDataSource.signUpWithEmail(email, password, languageCode, gender);
return res.fold(
(l) => Left(AuthenticationExc(message: l.toString())),
(r) => Right(
UserEntity(
accessToken: r.accessToken,
username: r.username,
gender: r.gender,
localeCode: r.localeCode,
),
),
);
} catch (e, s) {
MqCrashlytics.report(e, s);
log('signUpWithEmail: error: $e\n$s');
return Left(AuthenticationExc(message: e.toString()));
}
}

@override
Future<Either<UserEntity, Exception>> signInWithEmail(
String email,
String password,
String languageCode,
Gender gender,
) async {
aidaiym marked this conversation as resolved.
Show resolved Hide resolved
try {
final res = await remoteDataSource.signInWithEmail(email, password, languageCode, gender);
return res.fold(
Left.new,
(r) => Right(
UserEntity(
accessToken: r.accessToken,
username: r.username,
gender: r.gender,
localeCode: r.localeCode,
),
),
);
} catch (e, s) {
MqCrashlytics.report(e, s);
log('signWithEmail: error: $e\n$s');
return Left(AuthenticationExc(message: e.toString()));
}
}

@override
Future<Either<UserEntity, Exception>> signWithGoogle(
String languageCode,
Expand Down Expand Up @@ -106,6 +160,16 @@ final class AuthRepositoryImpl implements AuthRepository {
});
}

@override
Future<void> forgotPassword(String email) async {
try {
await remoteDataSource.forgotPasswordRemote(email);
} catch (e, s) {
MqCrashlytics.report(e, s);
log('Forgot Password error: $e\n$s');
}
}

aidaiym marked this conversation as resolved.
Show resolved Hide resolved
@override
Future<void> logout() async {
try {
Expand Down
101 changes: 101 additions & 0 deletions app/lib/app/data/source/auth_remote_data_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,103 @@ final class AuthRemoteDataSource {
final SoccialAuth soccialAuth;
final bool isIntegrationTest;

Future<Either<UserModelResponse, Exception>> signUpWithEmail(
String email,
String password,
String languageCode,
Gender gender,
) async {
aidaiym marked this conversation as resolved.
Show resolved Hide resolved
final signUpAuth = await _getSignUpAuth(email, password);

final token = await client.post(
apiConst.registerWithEmail,
fromJson: TokenResponse.fromJson,
body: {
'access_token': signUpAuth.accessToken,
},
);

return token.fold(
(l) => Left(Exception('Failed to sign up with email')),
(r) async {
final user = UserModelResponse(
accessToken: r.key,
username: signUpAuth.name,
gender: gender,
localeCode: languageCode,
);

await storage.writeString(key: StorageKeys.tokenKey, value: user.accessToken);

return Right(user);
},
);
}

Future<_UserReqParam> _getSignUpAuth(String email, String password) async {
if (isIntegrationTest) {
return const _UserReqParam(
name: 'Test User',
accessToken: r'myquran_te$t_t0ken',
);
} else {
final signUpAuth = await soccialAuth.signUpWithEmail(email, password);
final accessToken = signUpAuth.credential?.accessToken ?? '';
final username = signUpAuth.user?.displayName ?? '';
return _UserReqParam(
name: username,
accessToken: accessToken,
);
}
}

Future<Either<UserModelResponse, Exception>> signInWithEmail(
String email,
String password,
String languageCode,
Gender gender,
) async {
final signInAuth = await _getSignInAuth(email, password);

final token = await client.post(
apiConst.loginWithEmail,
fromJson: TokenResponse.fromJson,
body: {
'access_token': signInAuth.accessToken,
},
);

return token.fold(Left.new, (r) async {
final user = UserModelResponse(
accessToken: r.key,
username: signInAuth.name,
gender: gender,
localeCode: languageCode,
);

await storage.writeString(key: StorageKeys.tokenKey, value: user.accessToken);
aidaiym marked this conversation as resolved.
Show resolved Hide resolved

return Right(user);
});
}

Future<_UserReqParam> _getSignInAuth(String email, String password) async {
if (isIntegrationTest) {
return const _UserReqParam(
name: 'Test User',
accessToken: r'myquran_te$t_t0ken',
);
} else {
final signInAuth = await soccialAuth.signInWithEmail(email, password);
final accessToken = signInAuth.credential?.accessToken ?? '';
final username = signInAuth.user?.displayName ?? '';
return _UserReqParam(
name: username,
accessToken: accessToken,
);
}
}

aidaiym marked this conversation as resolved.
Show resolved Hide resolved
Future<Either<UserModelResponse, Exception>> signInWithGoogle(
String languageCode,
Gender gender,
Expand Down Expand Up @@ -141,6 +238,10 @@ final class AuthRemoteDataSource {
);
}

Future<void> forgotPasswordRemote(String email) async {
await soccialAuth.forgotPassword(email);
}

Future<void> logoutRemote() async {
await soccialAuth.logOut();
}
Expand Down
3 changes: 3 additions & 0 deletions app/lib/app/domain/domain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ export 'usecase/ser_user_data_user_case.dart';
export 'usecase/patch_gender_user_case.dart';
export 'usecase/patch_locale_code_use_case.dart';
export 'usecase/logout_use_case.dart';
export 'usecase/email_sign_up_usecase.dart';
export 'usecase/email_sign_in_usecase.dart';
export 'usecase/forgot_password_usecase.dart';
export 'entity/user_entity.dart';
export 'entity/user_data_entity.dart';
16 changes: 16 additions & 0 deletions app/lib/app/domain/repository/auth_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ import 'package:my_quran/core/core.dart';
abstract class AuthRepository {
UserEntity? get init;

Future<Either<UserEntity, Exception>> signUpWithEmail(
String email,
String password,
String languageCode,
Gender gender,
);

Future<Either<UserEntity, Exception>> signInWithEmail(
String email,
String password,
String languageCode,
Gender gender,
);

Future<Either<UserEntity, Exception>> signWithGoogle(
String languageCode,
Gender gender,
Expand All @@ -26,5 +40,7 @@ abstract class AuthRepository {
required String localeCode,
});

Future<void> forgotPassword(String email);

Future<void> logout() async {}
}
19 changes: 19 additions & 0 deletions app/lib/app/domain/usecase/email_sign_in_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:meta/meta.dart';
import 'package:my_quran/app/app.dart';
import 'package:my_quran/core/core.dart';

@immutable
final class EmailSignInUseCase {
const EmailSignInUseCase(this.repository);

final AuthRepository repository;

Future<Either<UserEntity, Exception>> call(
String email,
String password,
String languageCode,
Gender gender,
) {
return repository.signInWithEmail(email, password, languageCode, gender);
}
}
19 changes: 19 additions & 0 deletions app/lib/app/domain/usecase/email_sign_up_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:meta/meta.dart';
import 'package:my_quran/app/app.dart';
import 'package:my_quran/core/core.dart';

@immutable
final class EmailSignUpUseCase {
const EmailSignUpUseCase(this.repository);

final AuthRepository repository;

Future<Either<UserEntity, Exception>> call(
String email,
String password,
String languageCode,
Gender gender,
) {
return repository.signUpWithEmail(email, password, languageCode, gender);
}
}
13 changes: 13 additions & 0 deletions app/lib/app/domain/usecase/forgot_password_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:meta/meta.dart';
import 'package:my_quran/app/app.dart';

@immutable
final class ForgotPasswordUseCase {
const ForgotPasswordUseCase(this.repository);

final AuthRepository repository;

Future<void> call(String email) {
return repository.forgotPassword(email);
}
}
47 changes: 47 additions & 0 deletions app/lib/app/presentation/cubit/auth_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,58 @@ class AuthCubit extends Cubit<AuthState> {
this.getInitialUserUseCase,
this.googleSignIn,
this.appleSignIn,
this.emailSignIn,
this.emailSignUp,
this.serUserDataUseCase,
this.patchGenderUseCase,
this.patchLocaleCodeUseCase,
this.logoutUseCase,
this.forgotPasswordUseCase,
) : super(AuthState(user: getInitialUserUseCase.call));

final GetInitialUserUseCase getInitialUserUseCase;
final GoogleSignInUseCase googleSignIn;
final AppleSignInUseCase appleSignIn;
final EmailSignInUseCase emailSignIn;
final EmailSignUpUseCase emailSignUp;
final ForgotPasswordUseCase forgotPasswordUseCase;
final SerUserDataUseCase serUserDataUseCase;
final PatchGenderUseCase patchGenderUseCase;
final PatchLocaleCodeUseCase patchLocaleCodeUseCase;
final LogoutUseCase logoutUseCase;
bool passwordVisible = false;

Future<AuthState> signUpWithEmail(String email, String password) async {
final user = await emailSignUp(
email,
password,
state.currentLocale.languageCode,
state.gender,
);

user.fold(
(l) => emit(state.copyWith(exception: l)),
(r) => emit(state.copyWith(user: r)),
);

return state;
}

Future<AuthState> signInWithEmail(String email, String password) async {
final user = await emailSignIn(
email,
password,
state.currentLocale.languageCode,
state.gender,
);

user.fold(
(l) => emit(state.copyWith(exception: l)),
(r) => emit(state.copyWith(user: r)),
);

return state;
}

Future<AuthState> signInWithGoogle() async {
final user = await googleSignIn(
Expand Down Expand Up @@ -95,6 +134,14 @@ class AuthCubit extends Cubit<AuthState> {
}
}

Future<void> forgotPassword(String email) async {
try {
await forgotPasswordUseCase(email);
} catch (e) {
emit(state.copyWith(exception: Exception(e)));
}
}

Future<void> logout() async {
try {
await logoutUseCase.call();
Expand Down
3 changes: 3 additions & 0 deletions app/lib/app/presentation/view/app_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ class MyApp extends StatelessWidget {
GetInitialUserUseCase(context.read<AuthRepository>()),
GoogleSignInUseCase(context.read<AuthRepository>()),
AppleSignInUseCase(context.read<AuthRepository>()),
EmailSignInUseCase(context.read<AuthRepository>()),
EmailSignUpUseCase(context.read<AuthRepository>()),
SerUserDataUseCase(context.read<AuthRepository>()),
PatchGenderUseCase(context.read<AuthRepository>()),
PatchLocaleCodeUseCase(context.read<AuthRepository>()),
LogoutUseCase(context.read<AuthRepository>()),
ForgotPasswordUseCase(context.read<AuthRepository>()),
),
),
BlocProvider(
Expand Down
3 changes: 3 additions & 0 deletions app/lib/components/components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ export 'indicators/dot_indicator.dart';
export 'audio/seek_bar.dart';
export 'audio/audio_center_button.dart';
export 'alert/confirmation_dialog.dart';
export 'forms/custom_text_field.dart';
export 'forms/forgot_password_form.dart';
export 'forms/hide_password.dart';
Loading
Loading