Firebase (인증, Firestore)

Do Junggeun·2020년 9월 23일
0
post-thumbnail
  • 백엔드 없이 편하게 간단한 웹앱을 개발하기 위해 firebase를 이용하면 좋겠다는 생각에, 최근 며칠 동안 노마드 코더의 React와 Firebase로 하는 트위터 클론코딩 강의를 통해 Firebase의 기본 기능을 익혔다. 아래는 이후 내가 실제로 작성해본 코드와 내용을 간략히 정리한 것이다.

Firebase 시작하기

설치

npm install --save firebase

셋팅

import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
var firebaseConfig = {
  //... configuration
};
firebase.initializeApp(firebaseConfig); // Initialize
  • firebase를 사용하기 위해 위와 같이 필요한 기능(나의 경우 authfirestore)을 import하고, firebase 앱을 만들면 제공되는 configuration을 입력한 후 초기화 해준다.
export const firebaseInstance = firebase;
export const authService = firebase.auth();
export const dbService = firebase.firestore();
  • 또한 나는 firebase 관련 코드를 별도의 파일에 저장했기 때문에, 다른 컴포넌트에서 firebase를 사용할 수 있도록 export한다.

인증 기능

import { authService, firebaseInstance } from '../fbase.js';

셋팅에서 export한 firebaseInstanceauthService를 import 해준다.

const onLoginClick = async (event) => {
    const {
        target: { name },
    } = event;
    const provider = new firebaseInstance.auth.GoogleAuthProvider();
    await authService.signInWithRedirect(provider);
};
const onLogOutClick = async () => {
    await authService.signOut();
};
  • 나는 구글 로그인 기능만 사용했다. 적절한 컴포넌트(로그인 버튼)에 onClick={onLoginClick} 속성을 적용하면 구글 로그인 기능 구현 끝! (로그아웃도 마찬가지)
  • 이 때, async/await을 사용하여 로그인/로그아웃은 비동기로 진행되도록 처리했다.

DB (firestore)

import { authService, dbService } from '../fbase.js';
  • authServicedbService를 import 한다.

데이터 입력

onSubmit = async (event) => {
    event.preventDefault();
    await dbService.collection(authService.currentUser.uid).add({
        info: this.state,
        createdTime: Date.now(),
        createdName: authService.currentUser.displayName,
    });
  • 적절한 컴포넌트에 onSubmit={onSubmit} 속성을 적용해주면 된다.
  • 참고로 firestore는 noSQL 데이터베이스로, collection안에 여러 개의 doc들이 위치하고, 각각의 doc들에 여러 개의 key:value 데이터를 저장하는 방식이다. (collection 폴더 안에 doc들이 있는 것과 비슷)
  • 나의 경우 collection의 이름을 로그인한 유저의 uid 속성으로 설정했다. 참고로 doc의 이름은 firestore가 랜덤으로 생성해준다.
  • 내가 입력한 정보는 정보의 입력 시점(createdTime: Date.now()), 작성자의 이름(createdName: authService.currentUser.displayName : 나의 경우 구글 계정에 설정된 이름)과 info(this.state : 객체로 쓰여진 여러 정보들)다.

데이터 출력

useEffect(() => {
    dbService.collection(authService.currentUser.uid).orderBy("createdTime", "desc").onSnapshot((snapshot) => {
        const problemArray = snapshot.docs.map((doc) => ({
            id: doc.id,
            ...doc.data(),
        }));
        setProblems(problemArray);
    });
}, []);
  • React Hooks를 이용하였다.
  • 출력하려는 데이터의 collection 이름(나의 경우 authService.currentUser.uid을 collection 메소드의 인자로 준다. orderBy("createdTime", "desc")로 해당 collection의 docs들을 createdTime을 기준으로 정렬한다. 이후 onSnapshot을 이용해 problemArray에 데이터를 모아 problem hook에 저장한다.
  • 이 때, doc.id는 데이터 입력시 임의로 생성된 doc의 이름이다. 참고로 onSnapshot을 이용하면 firestore에 변화가 발생하면 실시간으로 출력 결과가 업데이트된다.

데이터 삭제

const onDeleteClick = async (problem) => {
    const ok = window.confirm('정말 삭제하시겠습니까??');
    if (ok) {
        await dbService.doc(`${authService.currentUser.uid}/${problem.id}`).delete();
    }
};
  • 적절한 컴포넌트에 onClick={onDeleteClick} 속성을 주면 원하는 docs를 삭제할 수 있다.
  • 이때 doc의 인자는 (collectionName/docId)야 한다. 나의 경우 collection의 이름은 authService.currentUser.uid이고, doc의 이름은 problem.id로 받아왔다.
async resetData() {
    if (window.confirm('정말 초기화 하시겠습니까?\n입력한 모든 데이터가 삭제됩니다.')) {
        await dbService
            .collection(authService.currentUser.uid)
            .get()
            .then((res) => {
                res.forEach((element) => {
                    element.ref.delete();
                });
            });
    }
}
  • 한 collection의 모든 docs를 한번에 삭제하는 기능은 기본적으로 제공되지 않는 것 같다. 위와 같이 resetData 함수를 작성해서 사용하면 된다.

0개의 댓글