class AuthScreen extends StatefulWidget {
const AuthScreen({super.key});
State<AuthScreen> createState() {
return _AuthScreenState();
}
}
final _firebase = FirebaseAuth.instance;
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();
try {
if (_isLogin) {
final userCredentials = await _firebase.signInWithEmailAndPassword(
email: _enteredEmail, password: _enteredPassword);
} else {
final userCredentials = await _firebase.createUserWithEmailAndPassword(
email: _enteredEmail, password: _enteredPassword);
}
} on FirebaseAuthException catch (e) {
if (e.code == 'email-already-in-use') {
//...
}
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.message ?? 'Authentication Fail'),
),
);
}
}
...
추가적으로 login이든 join이든 build메서드에 나올 ElevatedButton
에 메서드로서 들어갈 _submit 메서드를 작성한다.
여기서 원래는 http와 유효성 코드를 직접 작성해야하지만 flutter sdk에서 추가한 flutter_auth 패키지의 메서드로 매우 짧고 간결하게 구현했다.
또한 try-catch문에서 on ... catch (e)
구문으로 on
키워드에 타입을 지정해주면 IDE에서도 e
의 타입을 알 수 있어 보다 코드를 에러없이 작성할 수 있다.
참고로 위 signInWithEmailAndPassword
, createUserWithEmailAndPassword
메서드는 사용자가 로그인을 하면 토큰을 생성하여 사용자 기기의 메모리에 저장하고 있다가 FirebaseAuth.instance.signOut();
메서드를 사용하면 토큰을 삭제하여 로그아웃기능을 구현한다.
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';
}
return null;
},
onSaved: (newValue) {
_enteredEmail = newValue!;
},
),
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: (newValue) {
_enteredPassword = newValue!;
},
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _submit,
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context)
.colorScheme
.primaryContainer,
),
child: Text(_isLogin ? 'Log-in' : 'Sign-up'),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create an account'
: 'I already have an account'),
),
],
),
),
),
),
),
],
),
),
),
);
}
Widget