1. firebase cli 및 sdk를 이용하기 위해 몇 가지 세팅을 진행하자.
https://firebase.google.com/docs/flutter/setup?hl=ko&platform=ios
Flutter 앱에 Firebase 추가
의견 보내기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Flutter 앱에 Firebase 추가 plat_ios plat_android plat_web iOS+ Android 웹 기본 요건 아직 Flutter 앱이 없다면
firebase.google.com
1) npm install -g firebase-tools 설치하고 firebase 명령어에 입력 후 화면이 나오면 설치 성공
2) firebase login으로 파베 계정 로그인
3) dart pub global activate flutterfire_cli 설치
4) flutterfire configure 입력하면 실행할 수 없다고 나오는데, 다시 dart pub global activate flutterfire_cli 를 입력하면 path가 없다고 나옴 -> 시스템 환경 변수 path에 해당 경로 추가 하고 vsc 껐다 키기
5) 다시 flutterfire configure 를 입력하면 본인이 원하는 플랫폼(android, ios) 선택하고 엔터
--> 여기까지가 일반 초기화 세팅
6) flutter pub add firebase_core 설치
7) flutter pub add firebase_auth 설치 (위 파베 사이트 매뉴얼에는 없으나 auth를 하기 위해서 설치)
8) flutterfire configure로 한번 더 세팅 (플랫폼 동일하게)
그리고 아래와 같이 세팅
2. 파베 로그인 기능을 활용하기 위해 파베에서 몇가지 세팅을 하자
프로젝트를 새로 만들고, authentication 부분에 이메일/비밀번호부분을 선택하자. (구글,페북 로그인 등 다른 방법도 있음)
- main.dart
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:chat_app/screens/auth.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FlutterChat',
theme: ThemeData().copyWith(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 63, 17, 177)),
),
home: const AuthScreen(),
);
}
}
1) 파베 설치 이후, main 부분을 위와 같이 세팅해주고 재실행해준다. 파베 설치하면 아래 파일도 생성될텐데, 이건 일단 그대로 두자.
- screens/auth.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
final _firebase = FirebaseAuth.instance;
class AuthScreen extends StatefulWidget {
const AuthScreen({super.key});
@override
State<AuthScreen> createState() {
return _AuthScreenState();
}
}
class _AuthScreenState extends State<AuthScreen> {
final _form = GlobalKey<FormState>();
var _isLogin = true;
var _enteredEmail = '';
var _enteredPassword = '';
void _submit() async {
final isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
if (_isLogin) {
// log users in
} else {
try {
final userCredentials = await _firebase.createUserWithEmailAndPassword(
email: _enteredEmail, password: _enteredPassword);
print(userCredentials);
} on FirebaseAuthException catch (error) {
if (error.code == 'email-already-in-use') {
// ...
}
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error.message ?? 'Authentication failed.'),
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.primary,
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(
top: 30,
bottom: 20,
left: 20,
right: 20,
),
width: 200,
child: Image.asset('assets/images/chat.png'),
),
Card(
margin: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: _form,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Email Address'),
keyboardType: TextInputType.emailAddress,
autocorrect: false,
textCapitalization: TextCapitalization.none,
validator: (value) {
if (value == null ||
value.trim().isEmpty ||
!value.contains('@')) {
return 'Please enter a valid email address.';
}
return null;
},
onSaved: (value) {
_enteredEmail = value!;
},
),
TextFormField(
decoration:
const InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.trim().length < 6) {
return 'Password must be at least 6 characters long.';
}
return null;
},
onSaved: (value) {
_enteredPassword = value!;
},
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _submit,
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context)
.colorScheme
.primaryContainer,
),
child: Text(_isLogin ? 'Login' : 'Signup'),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create an account'
: 'I already have an account'),
),
],
),
),
),
),
),
],
),
),
),
);
}
}
1) 기본적 form 사용법은 이전 강의와 동일하다.
2)
if (_isLogin) {
// log users in
} else {
try {
final userCredentials = await _firebase.createUserWithEmailAndPassword(
email: _enteredEmail, password: _enteredPassword);
print(userCredentials);
} on FirebaseAuthException catch (error) {
if (error.code == 'email-already-in-use') {
// ...
}
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error.message ?? 'Authentication failed.'),
),
);
}
}
}
-firebase.createUserWithEmailAndPassword의 sdk를 통해서 쉽게 이메일과 패스워드로 회원가입이 가능하다.
-이 부분에서 그냥 catch가 아닌 on FirebaseAuthException을 붙인 이유는, 에러를 firebase에서 제공하는 에러만 잡겠다는 의미다. createUserWithEmailAndPassword에 마우스를 올려놓으면 에러코드들을 확인 할 수 있다.
- 위 방법을 통해 회원가입을 하면, 파베에 아래와 같이 계정이 등록된다. 파베 유저 관리 부분에는 비밀번호 재설정 이메일 보내기 등 기본적인 서비스들을 제공해준다.
- 스낵바를 이용해 에러 메시지 보여준다.
3) 나머지 부분은 눈으로 따라가 보면 이해 된다.
- 결과 화면