https://console.firebase.google.com/u/0/
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를 직접 추가, 수정, 삭제 등이 가능하다.
'웹 개발 > 웹 프로젝트 구현' 카테고리의 다른 글
Next.js의 API 라우트, riot api 개발 (0) | 2024.06.27 |
---|---|
인터넷 강의 학습 도우미 Learn on Air 개발(1) (0) | 2024.04.28 |
React, Express.js 초기 설정, DeprecationWarning, ESLint, npm audit (0) | 2024.04.04 |
JWT, Jinja2를 이용한 웹 게임 개발일지 (+세션과 토큰) (1) | 2024.03.21 |