본문 바로가기

Front-End/React

[React] Firebase / Firestore 연동

728x90

- 리액트를 활용해 웹 사이트를 만들 예정입니다. 이에 앞서, 가장 기본적인 회원가입 및 로그인을 구현해 볼 것입니다. Back-End 로 node.js, spring 등 고민했지만 아무래도 Firebase 가 비교적 간단하면서도 편리할 것 같아 이로 정했습니다.

 

#1 Firebase 계정 생성

 

1) 이는 구글 계정으로 간단하게 생성할 수 있습니다. 다음과 같이 Add project 를 눌러 프로젝트를 생성합니다.

 

Add project 를 눌러 프로젝트를 생성한다.

 

 

2) 생성한 프로젝트에 들어가서 왼쪽에 Authentication 에 들어가서 Sign-in method 에서 로그인 방법을 설정합니다. 우선 Email/Password 로 설정하였습니다.

 

Sign-in providers 설정

 

#2 firebase_config.js

 

firebase_config 파일을 만들어 firebase 및 firestore 을 연결하기 위한 기본적인 환경을 구성합니다.

 

// firebase_config.js

// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore/lite';
import firebase from 'firebase/compat/app';

// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = { /* 생략 */ };

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const firestore = getFirestore(app);
export {firestore};

 

#3 Login.js

 

사실, firebase 의 Authentication 을 사용해야 사용자의 로그인 비밀번호가 보안이 됩니다.

이 경우에는 사용자의 데이터를 Firestore Database 에 넣어보는 것을 공부해보고자 했기 때문에 일단 사용자의 이메일과 비밀번호를 모두 db에 넣어보았습니다. 이에 db 에서 이메일과 비밀번호를 가져와 값을 비교하는 작업이 추가되었습니다.

(Authentication 을 이용한 로그인과 회원가입 과정은 이어지는 포스트에 포스팅할 예정입니다.)

 

// Login.js

import React, { useState, useEffect } from 'react';
import {
	getAuth,
	createUserWithEmailAndPassword,
	signInWithEmailAndPassword,
} from 'firebase/auth';
import { auth, firestore } from '../components/firebase_config';
import { async } from '@firebase/util';
import { useNavigate } from 'react-router-dom';
import { addDoc, collection } from 'firebase/firestore/lite'; // db 접근
import 'firebase/auth';
import { doc, getDoc } from 'firebase/firestore/lite';

function Login() {
	const [loginEmail, setLoginEmail] = useState('');
	const [loginPw, setLoginPw] = useState('');
	const [isSignUp, setIsSignUp] = useState(true);
	const auth = getAuth();

	
	// input data의 변화가 있을 때마다 value 값을 변경해서 useState 해준다.
	const handleLoginEmail = e => {
		setLoginEmail(e.target.value);
	};
	const handleLoginPw = e => {
		setLoginPw(e.target.value);
	};

	// 회원가입 버튼 이벤트
	const onClickJoin = () => {
		console.log('Join button pressed');
		navigate('/join');
	};

	// 로그인 버튼 이벤트
	const onClickLogin = async () => {
		try {
			console.log('Login button pressed');
			const docUser = doc(firestore, 'user', loginEmail);
			console.log(`loginEmail : ${loginEmail}`);
			const docGetUser = await getDoc(docUser);
			const docGetPw = await docGetUser.data().password;
			console.log(`docGetPw = ${docGetPw}`);
			
			if (docGetUser.exists()) { // 이메일이 있고
				// 비밀번호가 맞으면 로그인 성공
				if (docGetPw === loginPw) {
					console.log('로그인 성공');
					console.log(`user : ${JSON.stringify(docGetUser.data())}`);
					navigate('/main');
				} else { // 비밀번호가 틀리면 로그인 실패
					console.log('비밀번호 틀림');
					alert('비밀번호가 틀립니다. 다시 입력해주세요.');
					setLoginPw('')
				}
			} else {
				console.log("로그인 정보 없음");
				alert('회원가입이 필요한 이메일입니다. 회원가입 페이지로 이동합니다.');
			}
		} catch (error) {
			console.error(error)
			alert('회원가입이 필요한 이메일입니다. 회원가입 페이지로 이동합니다.');
		}
	};

	return (
		<div className="login_join_form">
			<div>
				<p>
					<input type="text" id="userid" name="userid" placeholder="user@gmail.com" value={loginEmail} onChange={handleLoginEmail}/>
				</p>
				<p>
					<input type="password" id="userpw" name="userpw" placeholder="Password" value={loginPw} onChange={handleLoginPw}/>
				</p>
				<input id="login" type="button" value="로그인" onClick={onClickLogin} />
				<input id="join" type="button" value="회원가입" onClick={onClickJoin} />
			</div>
		</div>
	);
}

export default Login;

 

 

firebase 의 Authentication 을 사용하는 경우, 로그인 및 회원가입은 다음과 같이 작성하면 됩니다.

 

// Login.js
const onClickLogin = async () => {
	console.log('Login button pressed');
	const result = await signInWithEmailAndPassword(auth, loginEmail, loginPw);
	console.log(result);
};

// Join.js
const signup = async() => {
	console.log('Join button pressed');
	const result = await createUserWithEmailAndPassword(auth, loginEmail, loginPw);
	console.log(result);
}

 

#4 Join.js

 

Firestore Database 에 있는 컬렉션을 가지고 와서, 새로운 데이터를 추가합니다. 이 때 document 값이 랜덤으로 자동 생성되게 만들었습니다.

 

import React, { useState, useEffect } from 'react';
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
import { useNavigate } from 'react-router-dom';
import {firestore} from "../components/firebase_config";
import {addDoc, collection} from 'firebase/firestore';

function Join() {
    const [loginEmail, setLoginEmail] = useState("");
    const [loginPw, setLoginPw] = useState("");
    const [userName, setUserName] = useState("");

    const auth = getAuth();
    const navigate = useNavigate();
    
     //firestore의 user 컬렉션을 가져옴
     const usersCollectionRef = collection(firestore, "user");
    
     const signup = async () => {
         await addDoc(usersCollectionRef, {name:userName, email:loginEmail, password:loginPw});
     }
    
    return (
        <div className='join_form'>
            <p><input type="text" placeholder="Name" onChange={(e) => { setUserName(e.target.value); }}/></p>
            <p><input type="text" placeholder="Email" onChange={(e) => { setLoginEmail(e.target.value); }}/></p>
            <p><input type="password"placeholder="EmailPassword" onChange={(e) => { setLoginPw(e.target.value); }}/></p>
            <button onClick={signup}>회원가입</button><br/>
            <button onClick={() => (window.location.href = '/login')}>로그인 페이지로</button>
        </div>
    )

}

export default Join;

 

 

이렇게 회원가입 및 로그인 구현을 해보았습니다. 프로젝트 하면서 앞으로 관리해야할 사용자의 데이터들이 점점 많아질텐데, Firestore Database 를 잘 활용해보는 것이 좋을 것 같습니다.

728x90