feat: google sign in auth service

This commit is contained in:
akhdanre 2025-05-04 11:40:32 +07:00
parent 140b8f103c
commit 488479befa
6 changed files with 82 additions and 17 deletions

View File

@ -39,4 +39,11 @@ class UserController extends GetxController {
userImage.value = userEntity.picUrl; userImage.value = userEntity.picUrl;
email.value = userEntity.email; email.value = userEntity.email;
} }
void clearUser() {
userData = null;
userName.value = "";
userImage.value = "";
email.value = '';
}
} }

View File

@ -0,0 +1,35 @@
import 'package:google_sign_in/google_sign_in.dart';
class GoogleAuthService {
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'profile', 'openid'],
);
Future<GoogleSignInAccount?> signIn() async {
try {
return await _googleSignIn.signIn();
} catch (e) {
rethrow;
}
}
Future<void> signOut() async {
try {
await _googleSignIn.signOut();
} catch (e) {
rethrow;
}
}
Future<String?> getIdToken() async {
final account = await _googleSignIn.signIn();
if (account == null) return null;
final auth = await account.authentication;
return auth.idToken;
}
Future<bool> isSignedIn() async {
return await _googleSignIn.isSignedIn();
}
}

View File

@ -2,13 +2,15 @@ import 'package:get/get_core/get_core.dart';
import 'package:get/get_instance/get_instance.dart'; import 'package:get/get_instance/get_instance.dart';
import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/controllers/user_controller.dart';
import 'package:quiz_app/data/services/auth_service.dart'; import 'package:quiz_app/data/services/auth_service.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart'; import 'package:quiz_app/data/services/user_storage_service.dart';
import 'package:quiz_app/feature/login/controllers/login_controller.dart'; import 'package:quiz_app/feature/login/controllers/login_controller.dart';
class LoginBinding extends Bindings { class LoginBinding extends Bindings {
@override @override
void dependencies() { void dependencies() {
Get.lazyPut<GoogleAuthService>(() => GoogleAuthService());
Get.lazyPut(() => AuthService()); Get.lazyPut(() => AuthService());
Get.lazyPut(() => LoginController(Get.find<AuthService>(), Get.find<UserStorageService>(), Get.find<UserController>())); Get.lazyPut(() => LoginController(Get.find<AuthService>(), Get.find<UserStorageService>(), Get.find<UserController>(), Get.find<GoogleAuthService>()));
} }
} }

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:quiz_app/app/routes/app_pages.dart'; import 'package:quiz_app/app/routes/app_pages.dart';
import 'package:quiz_app/component/global_button.dart'; import 'package:quiz_app/component/global_button.dart';
import 'package:quiz_app/core/utils/logger.dart'; import 'package:quiz_app/core/utils/logger.dart';
@ -9,14 +8,21 @@ import 'package:quiz_app/data/entity/user/user_entity.dart';
import 'package:quiz_app/data/models/login/login_request_model.dart'; import 'package:quiz_app/data/models/login/login_request_model.dart';
import 'package:quiz_app/data/models/login/login_response_model.dart'; import 'package:quiz_app/data/models/login/login_response_model.dart';
import 'package:quiz_app/data/services/auth_service.dart'; import 'package:quiz_app/data/services/auth_service.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart'; import 'package:quiz_app/data/services/user_storage_service.dart';
class LoginController extends GetxController { class LoginController extends GetxController {
final AuthService _authService; final AuthService _authService;
final UserStorageService _userStorageService; final UserStorageService _userStorageService;
final UserController _userController; final UserController _userController;
final GoogleAuthService _googleAuthService;
LoginController(this._authService, this._userStorageService, this._userController); LoginController(
this._authService,
this._userStorageService,
this._userController,
this._googleAuthService,
);
final TextEditingController emailController = TextEditingController(); final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController(); final TextEditingController passwordController = TextEditingController();
@ -25,10 +31,6 @@ class LoginController extends GetxController {
final RxBool isPasswordHidden = true.obs; final RxBool isPasswordHidden = true.obs;
final RxBool isLoading = false.obs; final RxBool isLoading = false.obs;
final GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: ['email', 'profile', 'openid'],
);
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@ -81,22 +83,19 @@ class LoginController extends GetxController {
/// **🔹 Login via Google** /// **🔹 Login via Google**
Future<void> loginWithGoogle() async { Future<void> loginWithGoogle() async {
try { try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn(); final user = await _googleAuthService.signIn();
if (googleUser == null) { if (user == null) {
Get.snackbar("Error", "Google Sign-In canceled"); Get.snackbar("Error", "Google Sign-In canceled");
return; return;
} }
final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final idToken = await user.authentication.then((auth) => auth.idToken);
final idToken = googleAuth.idToken;
if (idToken == null || idToken.isEmpty) { if (idToken == null || idToken.isEmpty) {
Get.snackbar("Error", "Google sign-in failed. No ID Token received."); Get.snackbar("Error", "No ID Token received.");
return; return;
} }
final LoginResponseModel response = await _authService.loginWithGoogle(idToken); final LoginResponseModel response = await _authService.loginWithGoogle(idToken);
final userEntity = _convertLoginResponseToUserEntity(response); final userEntity = _convertLoginResponseToUserEntity(response);
await _userStorageService.saveUser(userEntity); await _userStorageService.saveUser(userEntity);

View File

@ -1,9 +1,12 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
import 'package:quiz_app/feature/profile/controller/profile_controller.dart'; import 'package:quiz_app/feature/profile/controller/profile_controller.dart';
class ProfileBinding extends Bindings { class ProfileBinding extends Bindings {
@override @override
void dependencies() { void dependencies() {
Get.lazyPut(() => ProfileController()); Get.lazyPut<GoogleAuthService>(() => GoogleAuthService());
Get.lazyPut(() => ProfileController(Get.find<UserStorageService>(), Get.find<GoogleAuthService>()));
} }
} }

View File

@ -1,10 +1,18 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:quiz_app/app/routes/app_pages.dart';
import 'package:quiz_app/core/utils/logger.dart'; import 'package:quiz_app/core/utils/logger.dart';
import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/controllers/user_controller.dart';
import 'package:quiz_app/data/services/google_auth_service.dart';
import 'package:quiz_app/data/services/user_storage_service.dart';
class ProfileController extends GetxController { class ProfileController extends GetxController {
final UserController _userController = Get.find<UserController>(); final UserController _userController = Get.find<UserController>();
final UserStorageService _userStorageService;
final GoogleAuthService _googleAuthService;
ProfileController(this._userStorageService, this._googleAuthService);
Rx<String> get userName => _userController.userName; Rx<String> get userName => _userController.userName;
Rx<String> get email => _userController.email; Rx<String> get email => _userController.email;
Rx<String?> get userImage => _userController.userImage; Rx<String?> get userImage => _userController.userImage;
@ -12,8 +20,19 @@ class ProfileController extends GetxController {
final totalQuizzes = 12.obs; final totalQuizzes = 12.obs;
final avgScore = 85.obs; final avgScore = 85.obs;
void logout() { void logout() async {
logC.i("Logout pressed"); try {
await _googleAuthService.signOut();
await _userStorageService.clearUser();
_userController.clearUser();
_userStorageService.isLogged = false;
Get.offAllNamed(AppRoutes.loginPage);
} catch (e, stackTrace) {
logC.e("Google Sign-Out Error: $e", stackTrace: stackTrace);
Get.snackbar("Error", "Gagal logout dari Google");
}
} }
void editProfile() { void editProfile() {