파이어베이스 사용 코드를 정리할 포스트다.
에뮬레이터 실행
firebase 홈페이지 콘솔과 같은 기능을 수행하며, 로컬 환경에서 작업할 수 있게 해준다.
루트에서 firebase emulators:start
를 터미널에 실행.
터미널로부터 아래와 같은 표를 볼 수 있다. (준비 끝)
Emulator | Host:Port | View in Emulator UI |
---|---|---|
Authentication 1 | 127.0.0.1:9099 | http://127.0.0.1:4000/auth |
Firestore | 127.0.0.1:8080 | http://127.0.0.1:4000/firestore |
Storage | 127.0.0.1:9199 | http://127.0.0.1:4000/storage |
에뮬레이터 연결 (in main.dart)
void main() async{
WidgetsFlutterBinding.ensureInitialized(); // 플러터앱과 바인딩
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
); // firebase 초기화
try {
await FirebaseAuth.instance.useAuthEmulator("localhost", 9099); /// 앞서 터미널로 부터 받은 Host:Port를 작성
FirebaseFirestore.instance.useFirestoreEmulator("localhost", 8080);
FirebaseStorage.instance.useStorageEmulator("localhost", 9199);
}catch(e) {
print(e);
}
runApp(MyApp());
}
회원가입
class SignUpScreen extends StatefulWidget {...}
class _SignUpScreenState extends State<SignUpScreen> {
/// 필요한 컨트롤러 들 선언.
TextEditingController emailTextController = TextEditingController();
TextEditingController pwdTextController = TextEditingController();
/// 중요
Future<bool> signUp(String emailAddress, String password) async {
try {
final credential =
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: emailAddress,
password: password,
);
/// 회원가입이 되면, user라는 컬렉션에 uid, email을 생성하고, 받은 값을 넣는다.
await FirebaseFirestore.instance.collection("users").add({
"uid": credential.user?.uid ?? "",
"email": credential.user?.email ?? "",
});
return true;
/// 인증 과련 코드
} on FirebaseAuthException catch (e) {
if (e.code == "weak-password") {
print("패스워드가 약합니다.");
} else if (e.code == 'email-already-in-use') {
print("이미 정보가 존재합니다.");
}
return false;
} catch (e) {
return false;
}
}
}.
TextFormField(
controller: pwdTextController,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: "비밀번호"),
obscureText: true, // 입력한 텍스트를 가린다.
validator: (value) {
// 입력된 값이 null이거나 비어이다면
if (value == null || value.isEmpty) {
return "비밀번호를 입력해주세요.";
}
return null;
},
),
MaterialButton (
onPressed : () async {
if(_formkey.currentState!.validate()) {
_formkey.currentState!.save(); //폼 체크
// 위에서 만든 signUp함수를 await 으로 선언.
//받은 값을 trim()으로 양 끝 공백 제거
final result = await signUp(
emailTextController.text.trim(),
pwdTextController.text.trim(),
);
if(result) {
//컨텍스트 존재 확인
if (context.mounted) {
//알림 띄우기
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("회원가입 성공"),
),
);
// 로그인 라우터로 이동
context.go("/login") ;
}
}else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("회원가입 실패"),
),
);
}
} //else
} // _formkey.currentState!.validate()
}
)
기본적으로 안드로이드는 http
접근을 허용하지 않음.
따라서 예외 처리가 필요.
android Developer를 보면, Pie(API28)부터 cleartext HTTP를 비활성화.
API29부터 http접근을 허용하려면 AndroidManifest.xml
에 android:usesCleartextTraffic="true"
로 설정 필요.
traffic = "true"와같이 띄어쓰기를 안하는게 좋다. (에러가 났음)
구글 로그인의 경우, 로컬 에뮬레이터에서 진행할 수 없다.
따라서, 기존 로컬auth
코드를 주석 처리 후 테스트 진행.
로컬 auth 주석 -> 파이어베이스(
not local
) 콘솔 -> 프로젝트 설정/SHA 인증서 지문 추가 -> 테스트
나는 해당과정에서 이슈가 발생해 약 두시간정도의 삽질이 있었다.
결론적으로 아래 커맨드를 통해 SHA1키를 생성했다.
//mac terminal anywhere
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
위 에러 이미지는 당시 캡쳐를 못해 인터넷에 같은 에러를 가져왔다.
내가 처음마주한 에러다. (사실 여기서 방향을 잘못 잡은 바람에 2시간이 걸렸다고 생각한다)
모두 실패 했을때, 예전 회사에서 SHA1 관련해서 생성했던 기억이 났다.
SHA1 flutter
로 구글에 검색하니, 수동으로 생성할 수 있었다. (GOT Google)
터미널을 통해 만들어진 SHA1
을 firebase android SHA 인증서 지문에 추가했다.
정상 작동을 확인하고 침대에 몸을 던졌다.