Notice
Recent Posts
Recent Comments
Link
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- fcm#메세지전송#안드로이드메세지#플러터메세지전송
- 마이봇#chatgpt#ai#인공지능
- mediasaop#webrtc#미디어서버#
- 커피#그라인더#통돌이 오픈 #로스팅#드립커피#생두#원두
- flutter#sqlite#chatGPT#
- 펫버틀러#서버연동#프로필등록#로그인서버연동#이미지#동영상#업로드용 화면#앱개발#플러터#반려생활#로딩바#loading bar#
- 마이봇#아이폰#아이폰심사#IT고시#
- 플러터#sms#mms#문자보내기
- 마이봇#챗봇
- 마이봇#API 설정
- 마이봇#문서챗봇#PDF#TEXT#유투브#챗봇만들기#랭체인# langchain#벡터데이터#자료검색#챗GPT#GPT4#챗지피티
- 임대사업자#리걸테크#legaltech#마이봇#챗봇#법률챗봇#임대사업자챗봇#chatgpt#
- PDF검색#PDF검색챗봇#NEXTJS#스터디#스타트업#랭체이#langchain#prisma#sqlite#
- flutter#ios#앱개발#마이봇#
- 쇼핑몰관리시스템#매입관리#시트메타#매입채널#엑셀업로드
- 로우코드#lowcode#erp#관리시스템#시트메이트#시트메타#엑셀업로드#엑셀다운로드#그리드#데이터관리#생산관리시스템#로그관리#히스토리#입력체크
- 광동온더그린#프랜즈#가상CC#스크린골프#
- firebase#message#메세지#플러터#안드로이드
- PDF#챗봇검색#서비스#GPT4#PGT3.5#GPT#랭체인#챗봇#CHATBOT#LLM#문서검색
- 시트메타#관리시스템#테이블연동#품목관리
- ax5#tree#grid#단계별 펼치기# depth #시트메타
- flutter#채팅창@메모창#url링크#날짜추가
- 플러터#
- 로우코드#ERP#관리시스템#상품관리#선택박스#자동화프로그램
- flutterfire configure#파이어베이스#플러터
- 마이봇#핸드폰대체#
- #창작#SNS#스포츠#반려동물#연애#과제#레시피#활동#건강#운세#글쓰기#비즈니스 #AI비서#챗GPT#CHATGPT
- figma#flutter#dhwise#피그마#플러터#피그마 to 플러터 #figma to flutter
- 마이봇#pdf챗봇#상담챗봇#faq챗봇#chatgpt#랭체인#llm
- postgres#vector
Archives
- Today
- Total
혼자서 앱 만드는 개발자 함께하는 AI 세상
[펫버틀러] 반려 동물 고민 상담 앱 - 개발 4 일차 (구글 로그인 등록) 본문
반응형
3일차 개발 문서 링크 - 지난 개발 FIREBASE 페이지 개발에 https://shsoft.tistory.com/63
- 로그인 페이지 작업 시 구글로그인을 사용한다.
- 구글로그인은 기본적으로 구글 권한 Authentication 항목에서 이메일/비밀번호 와 Google선택한다.
- 플러터에서 관련 pub add 를 추가해야한다.
- 현재 적용되어있는 firebase_auth 를 추가한다. 기본적으로
- firebase_core: ^2.3.0 firebase_auth: ^4.1.5 를 추가한다.
- SNS 구글 로그인
- 적용 소스 확인
여기서 GoogleSignInAccount? googleUser = await googleSignIn.signIn(); 부분이 구글 로그인을 호출하는 부분이다.
Future<bool> handleSignIn() async {
_status = Status.authenticating;
notifyListeners();
GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser != null) {
GoogleSignInAuthentication? googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
User? firebaseUser =
(await firebaseAuth.signInWithCredential(credential)).user;
return checkfirebaseUser(firebaseUser);
} else {
_status = Status.authenticateCanceled;
notifyListeners();
return false;
}
}
- 계정이 2개 이상 이면 선택 하지만 한 개 일 경우 홈 화면으로 바로 간다.
- 로그인 페이지 전체 공유
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:petbutler/constants/app_constants.dart';
import 'package:petbutler/constants/color_constants.dart';
import 'package:petbutler/providers/auth_provider.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import '../widgets/widgets.dart';
import 'login_add.dart';
import 'login_reset.dart';
import 'pages.dart';
class LoginPage extends StatefulWidget {
LoginPage({Key? key}) : super(key: key);
@override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
final _idTextEditController = TextEditingController();
final _passwordTextEditController = TextEditingController();
@override
Widget build(BuildContext context) {
var _idTextField = CupertinoTextField(
controller: _idTextEditController,
keyboardType: TextInputType.emailAddress,
placeholder: "이메일",
padding: EdgeInsets.all(10),
style: TextStyle(fontSize: 16),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black,
width: 0.5,
),
borderRadius: BorderRadius.circular(12),
),
onChanged: (text) {
setState(() {});
},
);
var _passwordTextField = CupertinoTextField(
controller: _passwordTextEditController,
placeholder: "비밀번호",
obscureText: true,
padding: EdgeInsets.all(10),
style: TextStyle(fontSize: 16),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.black,
width: 0.5,
),
borderRadius: BorderRadius.circular(12),
),
onChanged: (text) {
setState(() {});
},
);
AuthProvider authProvider = Provider.of<AuthProvider>(context);
switch (authProvider.status) {
case Status.authenticateError:
Fluttertoast.showToast(msg: "Sign in fail");
break;
case Status.authenticateCanceled:
Fluttertoast.showToast(msg: "Sign in canceled");
break;
case Status.authenticated:
Fluttertoast.showToast(msg: "Sign in success");
break;
default:
break;
}
return Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
height: MediaQuery.of(context).size.height * 1.50,
child: SingleChildScrollView(
padding: EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
height: 150.0,
),
Image.asset(
"images/pet/intro/intro_login2.png",
//width: 80,
height: 200,
),
SizedBox(
height: 10.0,
),
Text('펫버틀러 로그인',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15.0)),
SizedBox(
height: 10.0,
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: EdgeInsets.symmetric(horizontal: 15),
child: _idTextField,
),
Padding(
padding: EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: _passwordTextField),
SizedBox(
height: 10.0,
),
Container(
height: 45,
width: 250,
decoration: BoxDecoration(
color: Color.fromARGB(255, 244, 85, 85),
borderRadius: BorderRadius.circular(20)),
// ignore: deprecated_member_use
child: TextButton(
onPressed: () async {
try {
User? googleUser;
googleUser = (await authProvider.firebaseAuth
.signInWithEmailAndPassword(
email: _idTextEditController.text,
password: _passwordTextEditController.text))
.user;
if (googleUser?.emailVerified == true) {
authProvider
.checkfirebaseUser(googleUser)
.then((isSuccess) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
});
} else {
Fluttertoast.showToast(
msg: '이메일 확인 필요합니다. 메일확인부탁드립니다.');
}
//userData = (await _auth.signInWithEmailAndPassword(email: userName.toString(), password: userPassword.toString())).user;
} on FirebaseAuthException catch (e) {
print(e);
if (e.code == 'user-not-found') {
Fluttertoast.showToast(msg: '등록되지 않은 이메일입니다');
} else if (e.code == 'wrong-password') {
Fluttertoast.showToast(msg: '비밀번호가 틀렸습니다');
} else {
Fluttertoast.showToast(msg: "이메일 비밀번호가 입력되지않았습니다.");
}
}
},
child: const Text(
'로그인',
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
SizedBox(
height: 10,
),
Text('SNS 소셜 로그인',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15.0)),
SizedBox(
height: 10.0,
),
Container(
height: 40,
width: 250,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(20)),
// ignore: deprecated_member_use
child: ElevatedButton(
onPressed: () async {
authProvider.handleSignIn().then((isSuccess) {
if (isSuccess) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
}
}).catchError((error, stackTrace) {
Fluttertoast.showToast(msg: error.toString());
authProvider.handleException();
});
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(10),
primary: Color.fromARGB(255, 62, 136, 246),
//shadowColor: Colors.black, 그림자 추가하는 속성
minimumSize: Size.fromHeight(50), // 높이만 50으로 설정
elevation: 1.0,
shape: RoundedRectangleBorder(
// shape : 버튼의 모양을 디자인 하는 기능
borderRadius: BorderRadius.circular(20.0)),
),
child: Row(
//spaceEvenly: 요소들을 균등하게 배치하는 속성
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/glogo.png'),
Text(
'구글 로그인 하기',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15.0),
),
Opacity(
opacity: 0.0,
child: Image.asset('images/glogo.png'),
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginADDPage()),
);
},
style: ElevatedButton.styleFrom(
primary: Color.fromARGB(255, 116, 120, 126),
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
),
child: const Text(
' 회 원 가 입 ',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15),
),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginResetPage()),
);
},
style: ElevatedButton.styleFrom(
primary: Color.fromARGB(255, 116, 120, 126),
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
),
child: const Text(
'비밀번호 재설정',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15),
),
),
],
)
],
),
),
));
}
}
/*
Scaffold(
appBar: AppBar(
title: Text(
AppConstants.loginTitle,
style: TextStyle(color: ColorConstants.primaryColor),
),
centerTitle: true,
),
body: Stack(
children: <Widget>[
Center(
child: Image.asset(
"images/app_icon.png",
width: 100,
height: 100,
),
),
Center(
child: TextButton(
onPressed: () async {
authProvider.handleSignIn().then((isSuccess) {
if (isSuccess) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
}
}).catchError((error, stackTrace) {
Fluttertoast.showToast(msg: error.toString());
authProvider.handleException();
});
},
child: Text(
'Sign in with Google',
style: TextStyle(fontSize: 16, color: Colors.white),
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed))
return Color(0xffdd4b39).withOpacity(0.8);
return Color(0xffdd4b39);
},
),
splashFactory: NoSplash.splashFactory,
padding: MaterialStateProperty.all<EdgeInsets>(
EdgeInsets.fromLTRB(30, 15, 30, 15),
),
),
),
),
// Loading
Positioned(
child: authProvider.status == Status.authenticating
? LoadingView()
: SizedBox.shrink(),
),
],
));
}
}
*/
- 권한관련 페이지 공유
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:petbutler/constants/constants.dart';
import 'package:petbutler/models/models.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';
enum Status {
uninitialized,
authenticated,
authenticating,
authenticateError,
authenticateException,
authenticateCanceled,
}
class AuthProvider extends ChangeNotifier {
final GoogleSignIn googleSignIn;
final FirebaseAuth firebaseAuth;
final FirebaseFirestore firebaseFirestore;
final SharedPreferences prefs;
Status _status = Status.uninitialized;
Status get status => _status;
AuthProvider({
required this.firebaseAuth,
required this.googleSignIn,
required this.prefs,
required this.firebaseFirestore,
});
String? getUserFirebaseId() {
return prefs.getString(FirestoreConstants.id);
}
Future<bool> isLoggedIn() async {
//bool isLoggedIn = await googleSignIn.isSignedIn();
if (prefs.getString(FirestoreConstants.id)?.isNotEmpty == true) {
return true;
} else {
return false;
}
}
//벨루 프로토콜
Future<bool> handleSignIn() async {
_status = Status.authenticating;
notifyListeners();
GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser != null) {
GoogleSignInAuthentication? googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
User? firebaseUser =
(await firebaseAuth.signInWithCredential(credential)).user;
return checkfirebaseUser(firebaseUser);
} else {
_status = Status.authenticateCanceled;
notifyListeners();
return false;
}
}
Future<bool> checkfirebaseUser(User? firebaseUser) async {
if (firebaseUser != null) {
final QuerySnapshot result = await firebaseFirestore
.collection(FirestoreConstants.pathUserCollection)
.where(FirestoreConstants.id, isEqualTo: firebaseUser.uid)
.get();
final List<DocumentSnapshot> documents = result.docs;
if (documents.length == 0) {
// Writing data to server because here is a new user
firebaseFirestore
.collection(FirestoreConstants.pathUserCollection)
.doc(firebaseUser.uid)
.set({
FirestoreConstants.nickname: firebaseUser.displayName,
FirestoreConstants.photoUrl: firebaseUser.photoURL,
FirestoreConstants.id: firebaseUser.uid,
'createdAt': DateTime.now().millisecondsSinceEpoch.toString(),
FirestoreConstants.chattingWith: null
});
// Write data to local storage
User? currentUser = firebaseUser;
await prefs.setString(FirestoreConstants.id, currentUser!.uid);
await prefs.setString(
FirestoreConstants.nickname, currentUser.displayName ?? "");
await prefs.setString(
FirestoreConstants.photoUrl, currentUser.photoURL ?? "");
} else {
// Already sign up, just get data from firestore
DocumentSnapshot documentSnapshot = documents[0];
UserChat userChat = UserChat.fromDocument(documentSnapshot);
// Write data to local
await prefs.setString(FirestoreConstants.id, userChat.id);
await prefs.setString(FirestoreConstants.nickname, userChat.nickname);
await prefs.setString(FirestoreConstants.photoUrl, userChat.photoUrl);
await prefs.setString(FirestoreConstants.aboutMe, userChat.aboutMe);
}
_status = Status.authenticated;
notifyListeners();
return true;
} else {
_status = Status.authenticateError;
notifyListeners();
return false;
}
}
void handleException() {
_status = Status.authenticateException;
notifyListeners();
}
Future<void> handleSignOut() async {
_status = Status.uninitialized;
await firebaseAuth.signOut();
await googleSignIn.disconnect();
await googleSignIn.signOut();
}
}
728x90
반응형
'펫버틀러' 카테고리의 다른 글
[펫버틀러] 반려 동물 고민 상담 앱 - 개발 6 일차 (강아지 프로필 등록2 서버연동) (2) | 2022.12.25 |
---|---|
[펫버틀러] 반려 동물 고민 상담 앱 - 개발 5 일차 (강아지 프로필 등록) (3) | 2022.12.24 |
[펫버틀러] 반려 동물 고민 상담 앱 - 개발 3 일차 (FIREBASE 등록) (0) | 2022.12.23 |
[펫버틀러] 반려동물 고민상담 앱 - 개발 2일차 (인트로페이지INTRO page) (0) | 2022.12.23 |
[펫버틀러] 반려동물 고민상담 앱 - 개발 1일차 (아이콘 제작) (5) | 2022.12.22 |
Comments