Skip to content

Nein-to-Sick/bandi_official

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image

PlayStore AppStore

📑 목차

  1. 🌟 프로젝트 소개
  2. 📊 프로젝트 성과
  3. 🛠️ 기술 스택
  4. 🖼️ 앱 스크린샷
  5. 🏗️ 시스템 아키텍처
  6. 🚀 기술적 도전 과제 & 해결 방법
  7. 💻 코드 스니펫 (Cloud Functions)
  8. 👤 역할
  9. 📚 배운 점
  10. ✨ 한 줄 정리

🌟 프로젝트 소개

반디(Bandi) 는 AI 기반 감정 분석과 회고 기능을 제공하는 일상 감정 관리 플랫폼입니다.

  • 감정 일기 작성 및 자동 키워드 분석 기능을 Flutter와 Firebase 기반으로 구현하며, 데이터 흐름과 비동기 처리 경험 축적
  • ChatGPT 기반 맞춤형 회고 챗봇 구현, API 연동과 상태관리 최적화 학습
  • Firebase Cloud Messaging 활용 푸시 알림 설계, 앱-서버리스 연동 경험
  • DeepL API를 통한 다국어 지원 구현, Flutter Localization 적용 및 글로벌 사용자 확장 경험

📊 프로젝트 성과

✅ iOS AppStore & Android PlayStore 동시 출시, 실사용자를 대상으로 기술 구현 및 운영 경험 확보

🏆 K-Startup 예비창업패키지 지원 선정 🏆 제 13 회 창업경진대회 RPM 대상
image image
2024-04-29 2024-12-24
관련 기사 1 관련 기사 2 관련 기사 1 관련 기사 2
  • 🏆 캡스톤디자인 경진대회 우수상 (2024-06-03)
  • 🏆 POSTECH Mini-I-Corps 우수상 (2024-02-08)
  • 🏆 제 12 회 창업경진대회 RPM 장려상 (2023-11-30)
  • 🏆 SW Festival 문제해결 아이디어 공모전 장려상 (2023-11-17)
  • 🏆 SW 창업 경진대회 대상 (2023-10-27)

🛠️ 기술 스택

Frontend

Flutter Dart Provider Responsive UI

Backend & DB

Firebase Firestore Cloud Functions Cloud Messaging Firebase Auth

AI & 번역

OpenAI DeepL Flutter Localization

배포

Google Play App Store


🖼️ 앱 스크린샷

홈 화면 감정 일기 작성 감정 분석 결과
홈 일기 분석
챗봇 회고 알림 기능 다국어 지원
챗봇 알림 번역

🏗️ 시스템 아키텍처

flowchart TD

User((사용자)) -->|소셜 로그인| Auth[Google/Apple OAuth] --> Provider["상태관리\nProvider"] --> DB[(Firestore Database)]
User -->|일기 작성| Write[일기 작성]
Write --> Local[로컬 저장소]
Write --> DB

User -->|기록 공유| Share[공유된 기록]
Share -->|공감| Functions[Firebase Cloud Functions] -->|공감 / 알림 Trigger| FCM[Firebase Cloud Messaging] -->|알림| App[상대방앱]
Share -->|번역| DeepL[DeepL API]

Functions -->|AI 호출| OpenAI[ChatGPT API]
Loading

🔥 기술적 도전 과제 & 해결 방법

  1. 다국어화 및 번역 토글 구현

    • PR: #133 Feature 다국어화(localization) 설정하기
    • 내용: Flutter UI 전반과 Firebase Function에 다국어(Localization) 적용, 사용자 입력 일기 공유 시 DeepL API 기반 번역 토글 기능 구현
    • 의미: 글로벌 사용자 대상 확장 및 플랫폼 내 언어 선택 유연성 강화, Flutter와 서버리스 연동 실무 경험 확보
  2. 기록 공유의 신고 및 차단 기능 추가

    • PR: #144 Release 공유 알고리즘 개선 등
    • 내용: 공유된 일기에서 부적절한 콘텐츠에 대한 신고 및 차단 기능 도입, 커뮤니티 안전성 확보
    • 의미: 사용자 경험 중심의 책임 있는 서비스 운영
  3. 소셜 로그인 자동 무한 루프 오류 해결

    • PR: #136 Release 로그인 오류 수정
    • 내용: 자동 로그인 시 발생하던 무한 재시도 루프 버그 수정, 안정적인 로그인 흐름 확보
    • 의미: 원활한 사용자 흐름 보장 및 UX 개선
  4. 계정 탈퇴 기능 안정화 및 코드 개선

    • PR: #141 Fix 계정 탈퇴 버그 및 코드 개선
    • 내용: 계정 탈퇴 시 무한 로딩 문제 수정, Firebase DB 및 Auth 계정 삭제 로직 정상화, 재인증 기능 보완
    • 의미: 사용자 신뢰 확보 및 데이터 정합성 유지
  5. 인터넷 미연결 시 에러 핸들링 추가

    • PR: #123 Bug 인터넷 연결 시 에러 핸들링
    • 내용: 로그인 전 네트워크 연결 여부 확인 및 적절한 에러 메시지 처리 로직 추가
    • 의미: 네트워크 불안정 상황에서도 앱의 안정성 및 사용자 안내 강화

📂 코드 스니펫 (Cloud Functions)

Flutter와 Firebase를 단순히 사용하는 수준을 넘어, 실제 서비스에서 발생하는 이벤트 기반 기능을 직접 구현하며 클라이언트-서버리스 연동, 데이터 흐름, 비동기 처리를 깊이 탐구.
아래 코드는 이러한 경험을 통해 작성된, 공유된 일기 콘텐츠에 '좋아요'가 발생했을 때 작성자에게 실시간 알림을 전송하는 Cloud Function 예제.

// functions/index.js
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

// 좋아요 발생 시 작성자에게 알림 전송
exports.sendLikedDiaryNotification = functions.region("asia-northeast3").https.onCall(async (data, context) => {
    // [보안 1] 인증 확인: 로그인한 사용자만 호출 가능
    if (!context.auth) {
        throw new functions.https.HttpsError("unauthenticated", "로그인이 필요한 서비스입니다.");
    }

    // data.fcmToken은 보안상 신뢰할 수 없으므로 제거하고, DB에서 직접 조회합니다.
    const { likedDiaryId, userId } = data; // userId는 알림을 받을 대상(일기 작성자)

    // [보안 2] 필수 데이터 검증
    if (!likedDiaryId || !userId) {
        throw new functions.https.HttpsError("invalid-argument", "필요한 정보(likedDiaryId, userId)가 누락되었습니다.");
    }

    try {
        // [성능/보안] 알림 받을 유저 정보를 DB에서 한 번만 조회 (언어 설정 + FCM 토큰)
        const userDocRef = db.collection("users").doc(userId);
        const userDoc = await userDocRef.get();

        if (!userDoc.exists) {
            console.log(`[Error] Target user ${userId} not found.`);
            return { success: false, reason: "user_not_found" };
        }

        const userData = userDoc.data();
        const langCode = userData.language || "ko";

        // [보안 3] 클라이언트가 준 토큰이 아니라, DB에 저장된 신뢰할 수 있는 토큰 사용
        const targetFcmToken = userData.fcmToken;

        let notificationTitle = "";
        let notificationBody = "";
        const notificationType = "likedDiary";

        if (langCode === "ko") {
            notificationTitle = `누군가 나의 기록에 공감했어요!`;
            notificationBody = `나의 기록을 확인해보세요.`;
        } else {
            notificationTitle = `Someone reacted to your journal.`;
            notificationBody = `Take a look at your journal.`;
        }

        // 1. FCM 푸시 알림 전송
        if (targetFcmToken) {
            const message = {
                notification: {
                    title: notificationTitle,
                    body: notificationBody,
                },
                data: {
                    screen: "liked_diary_detail",
                    likedDiaryId: likedDiaryId,
                },
                token: targetFcmToken,
            };

            try {
                await admin.messaging().send(message);
                console.log(`[Success] Notification sent to user ${userId}`);
            } catch (fcmError) {
                // 토큰이 만료되었거나 삭제된 경우 등 에러 처리
                console.error(`[Warning] Failed to send FCM to user ${userId}: ${fcmError.message}`);
                // FCM 전송 실패가 DB 저장을 막으면 안 되므로 에러를 throw 하지 않음
            }
        } else {
            console.log(`[Info] User ${userId} has no FCM token. Skipping push notification.`);
        }

        // 2. 알림 내역 DB 저장 (이전에 개선한 함수 호출)
        await addNotification(userId, notificationTitle, notificationType, likedDiaryId);

        return { success: true };
    } catch (error) {
        console.error(`[Error] sendLikedDiaryNotification failed:`, error);
        throw new functions.https.HttpsError("internal", "알림 전송 중 오류가 발생했습니다.");
    }
});

👥 역할

이름 역할
김형진
Flutter 프론트엔드 & Firebase 백엔드 개발, Cloud Functions 및 서버리스 아키텍처 구현, ChatGPT API 연동 및 최적화, 배포 및 스토어 심사 대응
김경록
일기 작성 및 공유 기능 중심 개발, 대표 문서 체계 도입, DeepL API 기반 다국어화 적용
권세한
팀 내 역할 (개발/운영 보조)
박창휘
앱 디자인 총괄(UI/UX), 리서치 기반 앱 컨셉 및 브랜딩 전략 수립, UI 디자인 및 디자인 시스템 구축, 디자인 검수

📌 배운 점

  • 앱 심사와 서비스 운영 과정에서 발생하는 실제 문제 해결 경험 축적, Flutter/Firebase/Cloud Functions 적용 및 심화 이해
  • 소셜 로그인, 다국어, 네트워크 등 실무 난이도 높은 문제 해결 능력 확보
  • 실제 사용자 피드백 기반으로 지속적인 개선 사이클 운영

✨ 한 줄 정리

“실서비스를 개발·출시·운영하며, 복잡한 기술적 문제를 해결할 수 있는 풀스택 모바일 개발 경험”

About

LLM 기반 일상 감정 관리 플랫폼, 반디

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •