struct Report: Codable {
@DocumentID var id: String?
let reportReason: String // 신고 사유
let reportDetails: String // 상세 내용
let title: String // 게시글 제목
let reporterNickname: String // 신고자 닉네임
let creationTime: String // 작성 시간
let nickname: String // 신고받는 사람 닉네임
var toDictionary: [String: Any] {
return [
"reportReason": reportReason,
"reportDetails": reportDetails,
"title": title,
"reporterNickname": reporterNickname,
"creationTime": creationTime,
"nickname": nickname
]
}
}
struct Post: Identifiable, Codable {
@DocumentID var id: String?
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?
}
class ReportManager {
static let shared = ReportManager()
private let db = Firestore.firestore()
private let reportCollection = "reports"
private init() {}
func uploadReport(_ report: Report, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let data = try Firestore.Encoder().encode(report)
db.collection(reportCollection).addDocument(data: data) { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
} catch {
completion(.failure(error))
}
}
func getCurrentTime() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
return formatter.string(from: Date())
}
}
신고 기능의 핵심 로직은 다음과 같다:
@objc private func reportButtonTapped() {
// 1. 유효성 검사
guard let selectedReason = selectedReason else {
showAlert(title: "알림", message: "신고 사유를 선택해주세요.")
return
}
let description = reportDescriptionTextView.text ?? ""
if description.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
showAlert(title: "알림", message: "신고 내용을 입력해주세요.")
return
}
// 2. Report 객체 생성
let report = Report(
reportReason: selectedReason,
reportDetails: description,
title: post.title,
reporterNickname: reporterNickname,
creationTime: ReportManager.shared.getCurrentTime(),
nickname: post.nickName
)
// 3. Firebase에 업로드
ReportManager.shared.uploadReport(report) { [weak self] result in
switch result {
case .success:
self?.showCompletionAlert()
case .failure(let error):
self?.showAlert(title: "오류",
message: "신고 접수 중 오류가 발생했습니다: \(error.localizedDescription)")
}
}
}
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /reports/{report} {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update, delete: if false; // 신고는 수정/삭제 불가
}
}
}
func getReports(completion: @escaping (Result<[Report], Error>) -> Void) {
db.collection(reportCollection)
.order(by: "creationTime", descending: true)
.getDocuments { snapshot, error in
// 처리 로직
}
}
func checkReportLimit(userNickname: String, completion: @escaping (Bool) -> Void) {
db.collection(reportCollection)
.whereField("reporterNickname", isEqualTo: userNickname)
.whereField("creationTime", isGreaterThan: Date().addingTimeInterval(-86400))
.getDocuments { snapshot, _ in
let count = snapshot?.documents.count ?? 0
completion(count < 5) // 하루 5회로 제한
}
}