저번 시간에는 구글 로그인 인증 상태를 지속시키려면 어떻게 해야하는지 알아보았다. 오늘은 이메일 회원가입과 이메일 로그인을 구현해보려 한다.
sign up 버튼을 클릭하면 회원가입 창으로 넘어가도록 했다.
email과 password를 입력하는 input 2개와 Create User 버튼을 먼저 만들어 놓았다.
firebase authentication의 Users를 보면 지금까지는 나와 멘토님 2명의 구글 로그인 흔적만 보인다. 이제 test@gmail.com이라는 이메일과 1234567이라는 비밀번호로 회원가입을 하면????
심호흡) 하나, 둘, 셋!
띠용? 바뀐게 없고 에러만 난다.
FirebaseError: Firebase: Error (auth/operation-not-allowed)
당황하지 말자구~~ docs에 힌트가 다 있다.
제공된 로그인 제공업체가 사용 중지?.. 나는 사용 중지한적도 없고 제공한 적도 없.. 아!! 제공을 한 적이 없어서!???
firebase → Authentication → sign-in method → 새 제공업체 추가 → 이메일/비밀번호 클릭 → 사용 설정 toggle button 클릭 → 저장
짜잔! 추가되었어! 이제 될까??!
test@gmail.com이라는 이메일과 1234567이라는 비밀번호로 다시 시도해보자 두근두근
오오오오 뭔가 뜬다!!!
test@gmail.com이라는 이메일로 성공적으로 회원가입 완료!! 꺄악~~
import React, { useState } from "react";
import styled from "styled-components";
import { Link } from "react-router-dom";
import { createUserWithEmailAndPassword } from "firebase/auth";
import auth from "./service/firebase";
// styled components 생략
function SignUp() {
const [signUpEmail, setEmail] = useState("");
const [signUpPassword, setPassword] = useState("");
const handleRegister = async () => {
try {
const user = await createUserWithEmailAndPassword(
auth,
signUpEmail,
signUpPassword
);
console.log(user);
} catch (error) {
console.log(error);
}
};
return (
<>
<SignUpInputWrapper>
<SignUpForm>
<SignUpInput
placeholder='email'
onChange={(event) => {
setEmail(event.target.value);
}}
/>
<SignUpInput
placeholder='비밀번호'
onChange={(event) => {
setPassword(event.target.value);
}}
/>
</SignUpForm>
</SignUpInputWrapper>
<BtnWrapper>
<Link
to={{
pathname: `/mypage`,
}}
>
<Btn onClick={handleRegister}>Create User</Btn>
</Link>
<Link
to={{
pathname: `/`,
}}
>
<Btn>Back</Btn>
</Link>
</BtnWrapper>
</>
);
}
export default SignUp;
signUpEmail, signUpPassword라는 state를 생성하고, createUserWithEmailAndPassword를 이용하여 새로운 user를 생성한다.
email과 password input에는 onChange함수를 걸어주고 modify state하는 콜백함수를 전달한다.
Create User 버튼에는 handleRegister 콜백함수를 onClick에 전달한다.
회원가입을 성공적으로 구현했으니 내가 회원가입 시킨 이메일로 로그인도 시도해보자.
App에 onAuthStateChanged, signInWithEmailAndPassword, signOut를 새로 import해왔다.
import {
GoogleAuthProvider,
signInWithPopup,
setPersistence,
browserSessionPersistence,
onAuthStateChanged,
signInWithEmailAndPassword,
signOut,
} from "firebase/auth";
이번에는 jasmine@naver.com이라는 이메일로 회원가입을 완료해본 후 로그인을 시도해보려고 하는데.. 그런데..
FirebaseError: Firebase: Error (auth/invalid-email).
at createErrorInternal
invalid-email ??!! 유효하지 않다규??
한참 헤맸는데..
역시나 docs를 봐볼까?
문자열 이메일 주소여야 한다고??
내가 입력한 이메일 주소는 jasmine@naver.com인데..?
이게 문자열 이메일이 아니면 뭐람?
뭔가 전달이 잘못되고 있는게 분명하다..
.
.
2시간 후
.
.
2시간이 순삭되고 깨달았다. 알고보니 email input과 password input에 onChange 함수를 걸지 않았다.... onChange 함수를 안 걸었으니 useState에서 초기 state로 지정했던 빈 문자열로 로그인을 하고 있었던 것이었다......
난 허무할 때 힙합을 춰..
그래도 docs를 보고 오류의 종류를 파악했던 건 나름 도움이 되었다. 나의 치명적인 실수가 무엇이었는지 인지하기까지 시간이 조금이라도 단축되었달까??
onChange 함수를 성공적으로 걸었더니
두근두근 email login 클릭!
된다된다 email login도 된다!!!
import React, { useState } from "react";
import styled from "styled-components";
import { Link, useHistory } from "react-router-dom";
import {
GoogleAuthProvider,
signInWithPopup,
setPersistence,
browserSessionPersistence,
onAuthStateChanged,
signInWithEmailAndPassword,
signOut,
} from "firebase/auth";
import auth from "./service/firebase";
// styled-components 생략
function App() {
// email 로그인을 위해 상태변수를 만듦
const [loginEmail, setLoginEmail] = useState("");
const [loginPassword, setLoginPassword] = useState("");
const [user, setUser] = useState({});
const onChangeLoginEmail = (event: any) => {
console.log(event.target.value);
setLoginEmail(event.target.value);
};
const onChangeLoginPassword = (event: any) => {
console.log(event.target.value);
setLoginPassword(event.target.value);
};
// 로그인 함수
const handleEmailLogin = async () => {
try {
const user = await signInWithEmailAndPassword(
auth,
loginEmail,
loginPassword
);
console.log(user);
onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser as any);
});
history.push("/mypage");
} catch (error) {
console.log(loginEmail);
}
};
// 구글 로그인 코드 생략
return (
<>
<LoginInputWrapper>
<LoginForm>
<LoginInput placeholder='email' onChange={onChangeLoginEmail} />
<LoginInput placeholder='password' onChange={onChangeLoginPassword} />
</LoginForm>
</LoginInputWrapper>
<BtnWrapper className='App'>
<Btn onClick={handleEmailLogin}>Email Login</Btn>
<Link
to={{
pathname: `/sign-up`,
}}
>
<Btn>Sign-up</Btn>
</Link>
<Btn onClick={handleGoogleLogin}>Google Login</Btn>
</BtnWrapper>
</>
);
}
export default App;
loginEmail과 loginPassword라는 state을 만들고 onChangeLoginEmail과 onChangeLoginPassword라는 콜백함수를 만들고 login input에 걸어주었다.
로그인 구현을 위해 handleEmailLogin이라는 함수를 생성하였다. signInWithEmailAndPassword로 loginEmail과 loginPassword 정보를 받아 user를 정의한 다음, onAuthStateChanged로 currentUser를 변화시켜 로그인을 구현했다.
중간중간 오류날 때마다 리프레시하기 위해 회원가입 시킨 7명의 가상의 인물 ㅋㅋㅋㅋㅋㅋㅋㅋ
judy, coffee, jasmine2, test2, ready123, jasmine, test님 신규회원이 되신 걸 축하합니다
따끈따끈하게 deploy한 나의 앱!
https://learn-firebase-2ebf6.web.app
다음 시간에는 firebase-storage에 회원가입 데이터를 저장해보고, 회원 탈퇴를 구현해볼 것이다.
오늘도 수고했어 쪠스민 !! 맛있는 저녁 먹으러 갑니다 짜이찌앤~~~
🍚
참고:
https://firebase.google.com/docs/auth/admin/errors?hl=ko