Firebase를 활용한 게시글 CRUD 구현하기

호씨·약 11시간 전
0

Firebase를 활용한 게시글 CRUD 구현하기 🔥

Post 모델 구조체 생성 📝

먼저 게시글을 위한 데이터 모델을 다음과 같이 생성했다:

struct Post: Identifiable, Codable {
    @DocumentID var id: String? // Firestore 문서 ID (자동 생성)
    
    let nickName: String  
    let postType: String // "팀원 모집" 또는 "팀 합류"
    let title: String   
    let detail: String  
    let position: [String] 
    let techStack: [String]
    let ideaStatus: String  
    let meetingStyle: String  
    let numberOfRecruits: String  
    let createdAt: Date  
    
    // 팀원 모집 전용 필드 (옵셔널)
    var urgency: String? 
    var experience: String?
    
    // 팀 합류 전용 필드 (옵셔널)
    var available: String? 
    var currentStatus: String? 
}

PostService 구현 💻

게시글 CRUD 작업을 위한 Service 클래스는 다음과 같이 구현했다:

class PostService {
    static let shared = PostService()
    private let db = Firestore.firestore()
    private init() {}
    
    // Create
    func uploadPost(post: Post, completion: @escaping (Result<Void, Error>) -> Void) {
        do {
            let data = try Firestore.Encoder().encode(post)
            db.collection("posts").addDocument(data: data) { error in
                if let error = error {
                    completion(.failure(error))
                } else {
                    completion(.success(()))
                }
            }
        } catch {
            completion(.failure(error))
        }
    }
    
    // Read
    func getPostList(type: String, completion: @escaping (Result<[Post], Error>) -> Void) {
        db.collection("posts")
            .whereField("postType", isEqualTo: type)
            .order(by: "createdAt", descending: true)
            .getDocuments { snapshot, error in
                if let error = error {
                    completion(.failure(error))
                    return
                }
                
                guard let documents = snapshot?.documents else { return }
                
                let posts = documents.compactMap { document -> Post? in
                    try? document.data(as: Post.self)
                }
                completion(.success(posts))
            }
    }
    
    // Update
    func updatePost(id: String, post: Post, completion: @escaping (Result<Void, Error>) -> Void) {
        do {
            let data = try Firestore.Encoder().encode(post)
            db.collection("posts").document(id).updateData(data) { error in
                if let error = error {
                    completion(.failure(error))
                } else {
                    completion(.success(()))
                }
            }
        } catch {
            completion(.failure(error))
        }
    }
    
    // Delete
    func deletePost(id: String, completion: @escaping (Result<Void, Error>) -> Void) {
        db.collection("posts").document(id).delete { error in
            if let error = error {
                completion(.failure(error))
            } else {
                completion(.success(()))
            }
        }
    }
}

게시글 작성 구현 예시 (Upload) ✍️

@objc private func submitButtonTapped() {
    // 입력값 검증
    guard !selectedPositions.isEmpty,
          !selectedAvailable.isEmpty,
          let titleInput = uploadView.titleSection.textField.text,
          !titleInput.isEmpty else {
        basicAlert(title: "입력 필요", message: "빈칸을 채워주세요")
        return
    }
    
    // Post 객체 생성
    let post = Post(
        id: nil,
        nickName: "test",
        postType: postType.rawValue,
        title: titleInput,
        createdAt: Date()
    )
    
    // 서버에 업로드
    PostService.shared.uploadPost(post: post) { [weak self] result in
        switch result {
        case .success:
            self?.navigationController?.popViewController(animated: true)
        case .failure(let error):
            self?.basicAlert(title: "업로드 실패", message: "\(error)")
        }
    }
}

게시글 수정/삭제 구현 예시 🔄

@objc private func editButtonTapped() {
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

    // 수정 액션
    let editAction = UIAlertAction(title: "수정하기", style: .default) { [weak self] _ in
        guard let self = self,
              let post = self.post else { return }
        
        let uploadVC = JoinTeamUploadVC()
        uploadVC.isEditMode = true
        uploadVC.editPostId = post.id
        
        // 기존 데이터 설정
        uploadVC.selectedPositions = post.position
        uploadVC.selectedAvailable = post.available ?? ""
        
        self.navigationController?.pushViewController(uploadVC, animated: true)
    }

    // 삭제 액션
    let deleteAction = UIAlertAction(title: "삭제하기", style: .destructive) { [weak self] _ in
        guard let self = self,
              let post = self.post,
              let postId = post.id else { return }
        
        let alert = UIAlertController(title: "삭제 확인", 
                                    message: "정말 삭제하시겠습니까?", 
                                    preferredStyle: .alert)
        
        let confirmAction = UIAlertAction(title: "삭제", style: .destructive) { [weak self] _ in
            PostService.shared.deletePost(id: postId) { result in
                switch result {
                case .success:
                    DispatchQueue.main.async {
                        self?.navigationController?.popViewController(animated: true)
                    }
                case .failure(let error):
                    self?.basicAlert(title: "삭제 실패", message: "\(error)")
                }
            }
        }
        
        alert.addAction(confirmAction)
        alert.addAction(UIAlertAction(title: "취소", style: .cancel))
        
        self.present(alert, animated: true)
    }
    
    alert.addAction(editAction)
    alert.addAction(deleteAction)
    alert.addAction(UIAlertAction(title: "취소", style: .cancel))
    
    present(alert, animated: true)
}

주요 기능 🎯

게시글 작성 (Create)

  • 필수 입력값 검증
  • Firebase에 데이터 업로드

게시글 조회 (Read)

  • 게시글 타입에 따른 필터링
  • 작성일 기준 내림차순 정렬

게시글 수정 (Update)

  • 기존 데이터 유지 및 수정
  • 수정된 데이터 업데이트

게시글 삭제 (Delete)

  • 삭제 확인 프로세스
  • Firebase에서 데이터 삭제

구현 시 고려사항 ⚠️

  1. 사용자 입력값 검증
  2. 옵셔널 처리
  3. 에러 핸들링
  4. UI/UX 피드백 (얼럿 등)
  5. 데이터 일관성 유지

이러한 CRUD 기능을 통해 사용자들은 게시글을 작성하고, 수정하고, 삭제할 수 있으며, 다른 사용자들의 게시글도 볼 수 있도록 구현했다.

profile
이것저것 많이 해보고싶은 사람

0개의 댓글

관련 채용 정보