From 8a198f5635083b7f0410e8349536667d01884824 Mon Sep 17 00:00:00 2001 From: MKim Date: Wed, 2 Oct 2024 21:25:51 +0900 Subject: [PATCH] =?UTF-8?q?URI=20=EC=8A=A4=ED=82=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/feature/login/LoginScreen.dart | 71 ++++++++++++++++++- .../socialauth/SocialAuthService.dart | 14 +++- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/lib/feature/login/LoginScreen.dart b/lib/feature/login/LoginScreen.dart index 0a44e5f..edc5651 100644 --- a/lib/feature/login/LoginScreen.dart +++ b/lib/feature/login/LoginScreen.dart @@ -1,7 +1,12 @@ +import 'dart:async'; + import 'package:blueberry_flutter_template/feature/camera/CameraScreen.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:app_links/app_links.dart'; +import 'package:blueberry_flutter_template/utils/Talker.dart'; import '../../core/widget/SquareTitleWidget.dart'; import '../../services/FirebaseAuthServiceProvider.dart'; @@ -26,11 +31,73 @@ final wantEditNameProvider = StateProvider((ref) => false); ///# 로그인 화면 ///* 이메일, 소셜(구글,애플,깃허브) 로그인 기능 제공 -class LoginScreen extends ConsumerWidget { +class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { + LoginScreenState createState() => LoginScreenState(); +} + +class LoginScreenState extends ConsumerState { + StreamSubscription? _sub; + + //initAppLinks()는 초기 링크만 처리하고, 실시간 딥 링크 구독은 initState()에서 처리 + Future initAppLinks() async { + final appLinks = AppLinks(); + final initialLink = await appLinks.getInitialLink(); + if (initialLink != null) { + try { + handleDeepLink(initialLink); // 초기 딥링크 처리 + } catch (e) { + talker.error("초기 딥 링크 처리 중 오류 발생: $e"); + } + } + } + + Future handleDeepLink(Uri uri) async { + try { + if (uri.authority == 'login-callback') { + final firebaseToken = uri.queryParameters['firebaseToken']; + final String? name = uri.queryParameters['name']; + final String? profileImage = uri.queryParameters['profileImage']; + + if (firebaseToken != null) { + UserCredential userCredential = + await FirebaseAuth.instance.signInWithCustomToken(firebaseToken); + await userCredential.user?.updateDisplayName(name); + await userCredential.user?.updatePhotoURL(profileImage); + } else { + throw Exception('Firebase token이 존재하지 않습니다.'); + } + } + } catch (e) { + talker.error("딥 링크 처리 중 오류 발생: $e"); + } + } + + @override + void initState() { + super.initState(); + initAppLinks(); // 초기 딥 링크 처리 + + // 실시간 딥 링크 구독 + _sub = AppLinks().uriLinkStream.listen((Uri? link) { + if (link != null) { + handleDeepLink(link); + } + }, onError: (err) { + talker.error("딥 링크 수신 중 오류 발생: $err"); + }); + } + + @override + void dispose() { + _sub?.cancel(); // 구독 해제 + super.dispose(); + } + + @override + Widget build(BuildContext context) { // 페이지 정보를 가져오는 상태 관리 객체 final pageState = ref.watch(pageProvider); // 로그인 상태를 가져오는 상태 관리 객체 diff --git a/lib/services/socialauth/SocialAuthService.dart b/lib/services/socialauth/SocialAuthService.dart index 4a81f59..94102cc 100644 --- a/lib/services/socialauth/SocialAuthService.dart +++ b/lib/services/socialauth/SocialAuthService.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:math'; @@ -102,7 +103,18 @@ class SocialAuthService { final Uri url = Uri.parse( 'https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=$clientId&redirect_uri=$redirectUri&state=$state'); - await launchUrl(url); + + try { + final bool launched = + await launchUrl(url, mode: LaunchMode.externalApplication); + if (!launched) { + talker.error('네이버 로그인 URL 런칭 실패: $url'); + throw Exception('네이버 로그인 URL 런칭 실패'); + } + } catch (e) { + talker.error('네이버 로그인 URL 런칭 중 오류 발생: $e'); + throw Exception('네이버 로그인 중 오류 발생: $e'); + } } ///* 인증정보를 바탕으로 firestore에 저장하는 함수