728x90

https://console.firebase.google.com/u/0/

 

로그인 - Google 계정

이메일 또는 휴대전화

accounts.google.com

 

Firebase는 데이터가 변경될 때마다 클라이언트에 즉시 업데이트를 제공하여 실시간 애플리케이션에 유용하다.

다양한 인증 방법과 빠르고 안전한 웹 호스팅을 제공하며, SSL 인증서가 자동으로 제공되어 보안에도 좋다.

 

위 사이트에서 로그인을 한 뒤, 프로젝트를 생성하고 DB를 관리할 수 있는 Firestore에 접근해 api키를 볼 수 있다. 그리고 Firestore 규칙란에

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

이런식으로 내가 연결한 프로젝트의 전체 접근을 허용할 수 있고, 특정 유저만 접근 가능하게 권한설정도 가능하다.

 

firebase를 로컬환경으로 개발할땐, .env.local 파일에 firebase 관련 api키를 넣어놓는게 좋다.

 

아래는 리덕스툴킷을 사용한 firebase에서의 db삭제 예제이다.

import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { collection, getDocs, addDoc, updateDoc, deleteDoc, doc, query, orderBy, Timestamp } from 'firebase/firestore';
import { AppThunk } from './index';
import { db } from '../firebase/firebaseConfig';

...

deletePost(state, action: PayloadAction<string>) {
  state.posts = state.posts.filter(post => post.id !== action.payload);
}

...

export const removePost = (id: string): AppThunk => async (dispatch) => {
  try {
    const docRef = doc(db, 'posts', id);
    await deleteDoc(docRef);
    dispatch(deletePost(id));
  } catch (error) {
    console.error('Error deleting document: ', error);
  }
};

 

리덕스 툴킷을 사용하면 Date 객체를 상태나 액션에 저장하는 것이 매우 안좋다. 그래서 Date 객체를 직렬화 가능한 형태로 변환하여 저장하고 사용할 때는 다시 Date 객체로 변환해야한다.

interface BoardState {
  posts: { id: string; title: string; content: string, createdAt: string }[];
  loading: boolean;
  error: string | null;
}

...

addPost(state, action: PayloadAction<{ id: string; title: string; content: string; createdAt: string }>) {
  state.posts.unshift(action.payload);
},


...


  try {
    const q = query(collection(db, 'posts'), orderBy('createdAt', 'desc'));
    const querySnapshot = await getDocs(q);
    const posts = querySnapshot.docs.map((doc) => {
      const data = doc.data();
      return {
        id: doc.id,
        title: data.title,
        content: data.content,
        createdAt: (data.createdAt as Timestamp).toDate().toISOString() // Timestamp를 Date로 변환
      };
    });
    dispatch(fetchPostsSuccess(posts));
  }

 

app/duplicate-app오류는 firebase 앱을 초기화할 때 발생하는 오류이다. 동일한 앱이 이미 초기화되어 있는지 확인하고, 초기화되지 않은 경우에만 초기화하도록 해야한다.

 

@/firebase/firebaseConfig.ts

import { initializeApp, getApps, FirebaseApp } from 'firebase/app';
import { getFirestore, Firestore } from 'firebase/firestore';

interface FirebaseConfig {
  apiKey: string;
  authDomain: string;
  projectId: string;
  storageBucket: string;
  messagingSenderId: string;
  appId: string;
  measurementId?: string;
}

const firebaseConfig: FirebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY!,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN!,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET!,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID!,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID!,
  measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};

const apps: FirebaseApp[] = getApps();
let app: FirebaseApp;
if (apps.length === 0) {
  app = initializeApp(firebaseConfig);
} else {
  app = apps[0];
}

const db: Firestore = getFirestore(app);


export { db };

이미 초기화된 앱이 없다면 initializeApp을 호출하고, 있다면 그 앱을 재사용하게 해야 오류가 나지 않는다.

 

firebase 관리자는 db를 직접 추가, 수정, 삭제 등이 가능하다.

 

728x90

+ Recent posts