난 React native로 앱을 만들 때 firebase를 주로 사용했어. Firebase authenticate, Firebase firestore, Firebase Storage, Firebase function 이런 것들을 사용했었지. 사실 혼자서 백앤드까지 할 자신이 없어서 쉬워 보이는 거 찾다보니 google firebase랑 aws amplify 둘 중에 선택하게 되더라고 😅
난 결국 firebase를 선택했는데 amplify는 아직 본격적으로 사용해보지 않아서 잘 몰라. 게다가;;; flutter를 하고 있잖아? 그래서;;; 더더욱 amplify는 해볼 기회가 없어지네 ㅠㅠ 암튼 flutter나 firebase나 둘다 구글거니까 연동 잘되도록 만들어놨겠지? 일단 firebase에서 프로젝트를 하나 만들었어. 그리고 flutter 앱을 선택해보자구.
그러면 작업 단계가 나오는데 잘 따라해보자고!
다 잘 따라하면 되는데 누락된 단계가 좀 있네;;
►firebase_core 설치해줘야 하고~👇
%flutter pub add firebase_core
그 다음 main.dart에서
► main함수를 async로 선언해야 해. 그래야 await를 사용하니깐
► await firebase.initializeApp 불러오기 전에 WidgetsFlutterBinding.ensureInitialized(); 한줄 더 추가해 줘야해. 아니면 시뻘건 에러를 볼 수 있음.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MaterialApp(
title: 'Navigation',
home: MyApp(),
));
}
추가 안해주면 아래와 같은 에러 발생!
다 끝냈으면 디버그 일단 종료했다가 다시 시작해야해. 그러면 pod install 같은거 알아서 하거든. 다시 시작해서 앱이 잘 보이면 일단 연동은 끝~
자 이제 firebase authenticate 부터 시작해보자구. 우선 관련 패키지부터 설치 ㄱㄱ👇
%flutter pub add firebase_auth
그 다음에는 이메일과 비번으로 로그인할 수 있는 스크린을 하나 만들거야. 입력은 TextField를 사용했는데 이메일 validation 같은 것도 되는 TextFormField가 따로 있으니 각자 알아서 테스트 해보기~ 아래는 로그인 스크린 코드 👇👇👇
//ScreenLogin.dart
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
class ScreenLogin extends StatefulWidget {
const ScreenLogin({super.key});
@override
State<ScreenLogin> createState() => _ScreenLoginState();
}
class _ScreenLoginState extends State<ScreenLogin> {
final emailContoller = TextEditingController();//email 입력 컨트롤러
final passController = TextEditingController();//password 입력 컨트롤러
//원래 이것들 dispose시켜줘야하는데 귀찮아서 안해줌. 니들은 하자~
String errorString = '';//login error 보려고 만든 String state
//firebase auth login 함수, 이멜 + 비번으로 로그인
void fireAuthLogin() async {
print('${emailContoller.text}, ${passController.text}');//괜히 출력해봄.
await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: emailContoller.text, password: passController.text)
.catchError((error) => setState(() => errorString = error.message));
print("${FirebaseAuth.instance.currentUser}");//괜히 출력해 봄.
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(children: [
Container(
child: Center(
child: Image.asset("assets/images/peter.jpeg", width: 300),
)),
Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text(
"로그인하시던가",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
)),
Container(
margin: const EdgeInsets.all(5),
child: TextField(
controller: emailContoller,
decoration: InputDecoration(
border: OutlineInputBorder(), label: Text("e-mail")))),
Container(
margin: const EdgeInsets.all(5),
child: TextField(
controller: passController,
obscureText: true,//비번 *****<--- 으로 보이도록
decoration: InputDecoration(
border: OutlineInputBorder(), label: Text("password")),
)),
Container(
margin: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: Align(
alignment: Alignment.centerRight,
child: ElevatedButton(
onPressed: () => fireAuthLogin(),//로그인 버튼!
child: Text("로그인하라귯!"),
))),
Container(
margin: EdgeInsets.all(10),
child: Center(
child: Text(errorString),
))
]),
),
);
}
}
나는 심심해서 image도 넣고 했는데 똑같이 하려면 프로젝트에 assets/images 폴더 만들고 사진 추가 그리고 pubspec.yaml에다가 폴더도 등록해야해. 귀찮으면 빼버리자 ㅋ
로그인 화면은 어찌저찌 만들었는데... 원래 이래야 하잖아? 로그인이 안되어 있으면 로그인 화면으로, 로그인이 되어 있으면 main 화면으로.. 이걸 한번 해보자구. 이 방법도 찾아보니 여러가지가 있었는데 StreamBuilder를 사용하는게 가장 깔끔한 방법같더라고. 이해도 쉽고!
Stream은 대상(패치한 데이터 같은 거)이 변경될 때마다 수행되는 애라고 보면 되는데 FirebaseAuth.instance.authStateChanges() <---얘가 Stream<User?> 반환함 ㅇㅇ 결국 이 Stream에 따라 로그인 화면으로 갈지 메인 화면으로 갈지 결정하는 MainPage 위젯을 새로 하나 만들어야 해. 그리고 main()에서 MainPage 위젯을 불러와야겠지.👇👇 주석에다가 코드 설명해놨으니까 참고하고
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<User?>(//이건 스트림빌더임 ㅇㅇ
stream: FirebaseAuth.instance.authStateChanges(),//스트림에 authStateChanges를 등록함
//auth 상태가 변경되면 -> user가 로그인을 하던지, 로그아웃을 하던지, 계정 삭제를 하던지
builder: (context, snapshot) {//변경된 상태가 snapshot으로 빌드로 새로함.
if (snapshot.hasData) {//snapshot이 데이터가 있으면
return const MyApp();//기존의 MyApp() 위젯 빌드
} else {
return const ScreenLogin();//아니면 로그인해라~
}
},
));
}
}
음.. 나머지는 테스트용 로그아웃 버튼, 그리고 로그인한 유저 정보 화면에 표시하는 정도? 만 더 추가해 줬어. 로그아웃은 FirebaseAuth.instance.SignOut()함수를 사용하면 되고 유저 정보는 FirebaseAuth.instance.currentUser 를 통해서 읽어올 수 있어.
//로그아웃
...
TextButton(
onPressed: () => FirebaseAuth.instance.signOut(),
child: Text("로그아웃")),
...
//유저 정보 접근
...
Text("안녕! ${FirebaseAuth.instance.currentUser!.email}")
...
코드가 다 됐으면 firebase auth에 미리 이메일을 등록해두고 테스트를 해보자 👇👇👇
물론 이게 끝이 아니지. 계정을 새로 만드는 것도 해야하고 소셜 로그인도 해야 하는데... 음... 너무 길어지니까 다음 글에서 하자고... 너무 졸려! 안녕!
'Flutter > Flutter Study' 카테고리의 다른 글
[Flutter] - Firebase firestore (1) | 2022.10.12 |
---|---|
[Flutter] - Firebase auth! 소셜 로그인 (0) | 2022.10.12 |
React Native에서 Flutter로 갈아타기 #9 - Navigation 두번째 (0) | 2022.10.11 |
React Native에서 Flutter로 갈아타기 #8 - Navigation (0) | 2022.10.10 |
React Native에서 Flutter로 갈아타기 #7 - State management (2) | 2022.10.06 |