<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Riverpod on monkshark.dev</title><link>https://monkshark.github.io/tags/riverpod/</link><description>Recent content in Riverpod on monkshark.dev</description><generator>Hugo -- gohugo.io</generator><language>ko</language><lastBuildDate>Sun, 05 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://monkshark.github.io/tags/riverpod/index.xml" rel="self" type="application/rss+xml"/><item><title>#1 - 프로젝트를 시작한 이유</title><link>https://monkshark.github.io/p/hansol-app-intro/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><guid>https://monkshark.github.io/p/hansol-app-intro/</guid><description>&lt;h2 id="왜-만들었나"&gt;&lt;a href="#%ec%99%9c-%eb%a7%8c%eb%93%a4%ec%97%88%eb%82%98" class="header-anchor"&gt;&lt;/a&gt;왜 만들었나
&lt;/h2&gt;&lt;p&gt;고등학교 재학 중에 직접 느낀 불편함이 시작점이었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;급식 확인이 번거롭다.&lt;/strong&gt; 오늘 뭐 나오는지 알려면 매번 학교 홈페이지에 들어가서 주간 급식표를 찾아야 했다. 모바일에서 학교 홈페이지는 반응형도 아니라서, 핀치 줌으로 표를 확대해서 오늘 날짜를 찾는 과정을 매일 반복했다. 아침마다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;시간표 관리가 불편하다.&lt;/strong&gt; 종이 시간표를 사진 찍어 갤러리에 넣어두거나, 기억에 의존했다. 시간표가 바뀌면 다시 사진 찍고, 예전 사진은 삭제하고. 특히 2·3학년은 선택과목 때문에 반 친구와 시간표가 다른 경우가 많았는데, 이건 나중에 직접 부딪혀서야 알게 된 문제였다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;학교 커뮤니티가 없다.&lt;/strong&gt; 학생들끼리 소통할 수 있는 공간이 마땅치 않았다. 단체 카톡방은 있었지만, 익명 게시판이나 학년을 넘어선 소통 채널은 없었다.&lt;/p&gt;
&lt;p&gt;이 세 가지 문제를 하나의 앱으로 해결하고 싶었다. 급식, 시간표, 학사일정을 한눈에 보고, 게시판과 채팅으로 학교 구성원들이 소통할 수 있는 통합 플랫폼.&lt;/p&gt;
&lt;h2 id="기술-스택-선택"&gt;&lt;a href="#%ea%b8%b0%ec%88%a0-%ec%8a%a4%ed%83%9d-%ec%84%a0%ed%83%9d" class="header-anchor"&gt;&lt;/a&gt;기술 스택 선택
&lt;/h2&gt;&lt;p&gt;프로그래밍 기초는 있었지만 모바일 앱 개발은 처음이었다. 어떤 기술을 써야 하는지부터 조사해야 했다.&lt;/p&gt;
&lt;h3 id="flutter를-선택한-이유"&gt;&lt;a href="#flutter%eb%a5%bc-%ec%84%a0%ed%83%9d%ed%95%9c-%ec%9d%b4%ec%9c%a0" class="header-anchor"&gt;&lt;/a&gt;Flutter를 선택한 이유
&lt;/h3&gt;&lt;p&gt;처음에는 Java로 Android 네이티브 앱을 만들었다. Java를 조금 알고 있었으니까 진입이 가장 쉬웠다. 하지만 이후 학교에서 부스를 운영하면서 iOS 사용자가 절반이라는 걸 알게 되었고, 크로스플랫폼이 필수라는 결론에 도달했다. (&lt;a class="link" href="https://monkshark.github.io/p/java-to-flutter/" &gt;#2 - Java에서 Flutter로&lt;/a&gt;에서 자세히 다룬다.)&lt;/p&gt;
&lt;p&gt;Flutter를 선택한 이유:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;크로스 플랫폼&lt;/strong&gt; — Android + iOS를 하나의 코드베이스로. 1인 개발에서 두 플랫폼을 따로 만드는 건 비현실적이었다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dart 언어&lt;/strong&gt; — Java에서 넘어오기에 문법이 친숙했다. 타입 안전성이 있으면서도 컬렉션 API가 간결해서 데이터 파싱에 유리했다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;핫 리로드&lt;/strong&gt; — 코드를 수정하면 앱을 재시작하지 않아도 바로 화면에 반영된다. Java + XML 시절에는 빌드 후 에뮬레이터에 올리는 데 수십 초가 걸렸는데, 그 시간이 거의 0으로 줄었다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="firebase를-선택한-이유"&gt;&lt;a href="#firebase%eb%a5%bc-%ec%84%a0%ed%83%9d%ed%95%9c-%ec%9d%b4%ec%9c%a0" class="header-anchor"&gt;&lt;/a&gt;Firebase를 선택한 이유
&lt;/h3&gt;&lt;p&gt;백엔드를 직접 만들 수 있는 능력이 없었다. 서버 구축, DB 관리, API 설계 — 전부 처음이었다. Firebase는 이 모든 걸 건너뛸 수 있게 해줬다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Firestore&lt;/strong&gt; — NoSQL 문서 데이터베이스. 스키마가 유연해서 프로토타이핑이 빠르다. 실시간 스트림으로 게시글이나 채팅이 작성 즉시 다른 사용자에게 반영된다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firebase Auth&lt;/strong&gt; — Google, Apple, Kakao, GitHub 4종 OAuth 로그인을 빠르게 붙일 수 있었다 (&lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#data/auth_service.md" target="_blank" rel="noopener"
 &gt;인증 서비스 문서&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloud Storage&lt;/strong&gt; — 게시글 이미지, 프로필 사진 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FCM&lt;/strong&gt; — 댓글, 채팅, 공지 등 13종 푸시 알림 (&lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#notification/fcm_service.md" target="_blank" rel="noopener"
 &gt;FCM 서비스 문서&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;무료 한도&lt;/strong&gt; — 학교 앱 규모(1,000명 이내)에서는 Spark 플랜으로 월 $0~3 운영이 가능했다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="상태-관리-riverpod"&gt;&lt;a href="#%ec%83%81%ed%83%9c-%ea%b4%80%eb%a6%ac-riverpod" class="header-anchor"&gt;&lt;/a&gt;상태 관리: Riverpod
&lt;/h3&gt;&lt;p&gt;처음에는 Provider를 썼다. 간단한 CRUD에서는 문제가 없었지만, 기능이 복잡해지면서 한계가 드러났다. Provider는 BuildContext에 의존하기 때문에 위젯 트리 바깥에서 상태에 접근하기가 번거롭고, 테스트도 까다로웠다.&lt;/p&gt;
&lt;p&gt;Riverpod 2.5로 전환했다. 결정적인 이유 세 가지:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;AsyncNotifier&lt;/code&gt;&lt;/strong&gt; — 비동기 작업의 로딩/성공/에러 상태를 분기하는 코드가 깔끔해졌다. &lt;code&gt;.when(loading: ..., data: ..., error: ...)&lt;/code&gt;으로 한 줄에 처리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;family&lt;/code&gt; + &lt;code&gt;autoDispose&lt;/code&gt;&lt;/strong&gt; — 파라미터별로 별도 상태를 만들되, 사용하지 않으면 자동으로 메모리에서 해제. 게시글 목록처럼 화면을 벗어나면 필요 없는 상태를 관리하기에 적합&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BuildContext 독립&lt;/strong&gt; — 위젯 트리 바깥(서비스 레이어, 백그라운드 로직)에서도 상태에 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BLoC도 고려했지만, 단순 CRUD에도 Event 클래스와 State 클래스를 별도로 만들어야 하는 보일러플레이트가 과도하다고 판단했다. 학교 앱의 대부분의 기능은 &amp;ldquo;Firestore에서 데이터를 가져와서 보여주는&amp;rdquo; 패턴이라, Riverpod의 간결한 API가 더 맞았다.&lt;/p&gt;
&lt;h2 id="처음-설계한-핵심-기능"&gt;&lt;a href="#%ec%b2%98%ec%9d%8c-%ec%84%a4%ea%b3%84%ed%95%9c-%ed%95%b5%ec%8b%ac-%ea%b8%b0%eb%8a%a5" class="header-anchor"&gt;&lt;/a&gt;처음 설계한 핵심 기능
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;NEIS API 연동&lt;/strong&gt; — 교육부 공공데이터 API로 &lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#api/meal_data_api.md" target="_blank" rel="noopener"
 &gt;급식&lt;/a&gt;, &lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#api/timetable_data_api.md" target="_blank" rel="noopener"
 &gt;시간표&lt;/a&gt;, 학사일정 자동 수집&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4종 OAuth 로그인&lt;/strong&gt; — Google, Apple, Kakao, GitHub (&lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#data/auth_service.md" target="_blank" rel="noopener"
 &gt;인증 서비스 문서&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;게시판 + 1:1 채팅&lt;/strong&gt; — 학생·교사·졸업생·학부모 모두 사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;역할 기반 권한&lt;/strong&gt; — 일반 사용자, 매니저, 관리자 3단계&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;푸시 알림&lt;/strong&gt; — 댓글, 채팅, 공지 등 13종 (&lt;a class="link" href="https://monkshark.github.io/hansol_hs_flutter_app/#notification/fcm_service.md" target="_blank" rel="noopener"
 &gt;FCM 서비스 문서&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;처음부터 이 모든 기능을 계획한 건 아니었다. 급식과 시간표로 시작해서, 부스에서 받은 피드백으로 선택과목 시간표를 만들고, 사용자가 늘면서 게시판과 채팅을 붙이고, 관리가 필요해져서 역할 시스템을 추가했다. 하나씩 필요에 의해 붙여나간 결과가 지금의 프로젝트다.&lt;/p&gt;
&lt;p&gt;2023년 12월 첫 커밋부터 지금까지, 312개의 커밋, 110개의 Dart 파일, 32,000줄 이상의 코드. 이 시리즈는 그 과정에서 겪은 기술적 결정들을 기록한다.&lt;/p&gt;
&lt;h2 id="다음-글에서는"&gt;&lt;a href="#%eb%8b%a4%ec%9d%8c-%ea%b8%80%ec%97%90%ec%84%9c%eb%8a%94" class="header-anchor"&gt;&lt;/a&gt;다음 글에서는
&lt;/h2&gt;&lt;p&gt;Java 프로토타입 159커밋을 만들고, 학교 부스에서 결정적인 피드백을 받고, Flutter로 전환하기까지의 과정을 다룬다.&lt;/p&gt;</description></item></channel></rss>