Firebase Authentication, Firestore 기능을 이용해 로그인, 회원가입 기능을 구현할 것이다.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
const handleGoogleSignIn = async (e) =>{
e.preventDefault();
const provider = new GoogleAuthProvider(); //Google 제공업체 객체의 인스턴스 생성
const auth = getAuth(); //Firebase authentication 객체 생성
try{
const data = await signInWithPopup(auth, provider);
//팝업창을 이용하여 로그인 과정 진행 (비동기 작업)
const uid = data.user.uid; //로그인 시 사용자의 uid 필요
const response = await dispatch(signInUser(uid))
//Redux 액션을 사용하여 사용자의 로그인 정보를 redux 스토어에서 관리하는데 사용
//액션의 응답을 확인하여 사용자가 이미 회원가입한 경우와 아직 회원가입하지 않은 경우를 구분
if(response.payload === false){
alert('회원가입을 진행해주세요')
navigate('/signup')
}else{
navigate('/');
}
}
catch(error){
console.log(error);
}
}
const handleEmailSignIn = async (e) => {
e.preventDefault();
const auth = getAuth();
try{
const data = await signInWithEmailAndPassword(auth, Email, Password)
//이메일과 비밀번호로 로그인, 로그인한 사용자 세부 정보를 반환해줌
const uid = data.user.uid;
const response = await dispatch(signInUser(uid)) //signInUser라는 액션에 uid를 넣어줌
if(response.payload === false){
alert('회원가입을 진행해주세요')
navigate('/signup')
}else{
navigate('/');
}
}catch(error){
console.log(error);
}
}
const handleGoogleSignUp = async (e) =>{
e.preventDefault();
const provider = new GoogleAuthProvider(); //Google 제공업체 객체의 인스턴스 생성
const auth = getAuth();
try{
const data = await signInWithPopup(auth, provider); //팝업창을 이용하여 로그인 과정 진행 (비동기 작업)
console.log(data);
const uid = data.user.uid; //로그인 시 사용자의 id 필요
console.log("uid : ",uid);
const response = await findUser(uid)
console.log(response);
if(response.payload === false){
setUserName(data.user.displayName);
setEmail(data.user.email);
setUid(data.user.uid);
setVisible(!Visible);
}else{
alert('이미 회원가입 되어 있는 상태입니다. 로그인 하세요')
navigate('/signin')
}
}
catch(error){
console.log(error);
}
const handleEmailSignUp = (e) => {
e.preventDefault();
const auth = getAuth();
createUserWithEmailAndPassword(auth, Email, Password)
.then((userCredential)=>{
//Signed in
const user = userCredential.user;
console.log(user);
setEmail(user.email);
setUid(user.uid);
// 계정 생성 성공한 후 RegisterForm 컴포넌트를 렌더링
setVisible(!Visible);
})
.catch((error)=>{
// 오류 처리
const errorCode = error.code;
if(errorCode === "auth/email-already-in-use"){
alert("이미 사용중인 이메일 주소입니다. 다른 이메일 주소를 사용하세요")
}else{
console.log(error);
}
})
const onSubmit = async(e)=>{
e.preventDefault();
let variable = {
Uid: Uid,
UserName: UserName,
Email: Email,
Nickname: Nickname,
}
try{
const response = await dispatch(signUpUser(variable))
if(response.payload === "success"){ //회원가입이 성공적으로 이루어진 경우, 사용자를 홈 페이지로 리디렉션
navigate('/')
}
}catch(error){
throw error;
}
}
onSubmit 함수
//Actions
const SIGN_IN = 'user_reducer/signin';
const SIGN_UP = 'user_reducer/signup'
// Action Creators
export function signInUser(uid){
const result = findUser(uid);
return {
type: SIGN_IN, //type: 액션의 유형
payload: result //payload: 액션과 함께 전달되는 데이터 포함
};
};
export async function signUpUser(userdata){
const result = await saveUser(userdata);
console.log(result);
return{
type: SIGN_UP,
payload: result
}
}
SIGN_IN
및 SIGN_UP
액션을 처리loginSuccess
와 register
필드를 업데이트하여 사용자의 로그인 및 회원가입 상태를 관리//Reducer
export default function (state = {}, action){
switch (action.type) {
case SIGN_IN:
return {...state, loginSuccess: action.payload} //state를 똑같이 가져오고, user_actions의 payload를 넣어줌
case SIGN_UP:
return {...state, register: action.payload}
default:
return state;
}
}
findUser
함수는 사용자 UID를 기반으로 Firestore에서 사용자를 검색const users = firestore.collection("users");
를 사용하여 "users" 컬렉션에 대한 참조를 얻음await users.where("Uid", "==", uid).get();
를 사용하여 Uid
필드가 주어진 UID와 일치하는 문서들을 검색snapshot.size
를 사용하여 검색된 결과의 문서 수를 확인하고, 결과가 1개 이상인 경우에는 true를 반환하고, 그렇지 않으면 false를 반환try-catch
블록을 사용saveUser
함수는 사용자 데이터를 Firestore에 저장await users.doc(userdata.Uid).set(userdata);
를 사용하여 주어진 UID를 가진 문서에 사용자 데이터를 저장try-catch
블록을 사용