[TIL] Flutter 9기 사전 캠프 Day 11-1 : 투두앱 StatefulWidget CRUD 기능 구현 & Firebase & Firestore

현서·2025년 11월 21일

[TIL] Flutter 9기

목록 보기
12/102
post-thumbnail

📝 StatefulWidget CRUD

CRUD란?

CRUD는 데이터 처리의 기본적인 4가지 동작을 의미하는 약어
데이터를 다루는 대부분의 앱에서 CRUD는 핵심 개념입니다.

약어의미설명
CCreate새로운 데이터를 생성 (예: 할 일 추가)
RRead기존 데이터를 읽어오기 (예: 할 일 목록 보기)
UUpdate기존 데이터를 수정 (예: 할 일 내용 수정)
DDelete데이터를 삭제 (예: 완료한 할 일 제거)

StatefulWidget에서의 예시

  • Create: TextField에 입력 → setState()로 리스트에 추가
  • Read: ListView.builder로 리스트 항목 출력
  • Update: 리스트 항목을 EditableText나 다이얼로그로 수정
  • Delete: 체크박스, 삭제 버튼 등으로 항목 제거

Create 구현

투두 데이터를 담을 그릇(클래스)
투두 항목 하나하나를 객체처럼 다루기 위해 Todo 클래스를 정의
각 투두 항목은 다음과 같은 정보들을 담는다
title: 할 일 내용
isDone: 완료 여부

// todo.dart
class Todo {
  String title;
  bool isDone;

  Todo({
    required this.title,
    required this.isDone,
  });
}

만들지 않는다면?

투두 데이터를 그냥 문자열 또는 Map
체크박스 상태를 개별로 관리하기 어렵고
수정/삭제할 때 구조가 지저분해지고 유지보수가 힘들어짐

생성하고 담아놓을 목록을 HomePage에 선언

  List<Todo> todoList = [];

TextField의 onSubmitted 와 suffixIcon 이 터치되었을 때 실행되는 함수
{todoList 에 새로운 Todo 객체를 추가하고 TextField를 초기화}
똑같은 코드가 사용될거라 onCreate 라는 함수를 만들어 구현

  void onCreate() {
    if (textController.text.trim().isNotEmpty) {
      setState(() {
        todoList.add(Todo(title: textController.text, isDone: false));
      });
      textController.clear();
    }
  }

Read 구현

투두 데이터가 담겨있는 그릇을 ListView 에 뿌리기
List에 있는 변수를 반복적으로 뿌려줄 땐 ListView.builder
또 사이사이 공백이 존재하니 ListView.seperated 로 만들기

      body: ListView.separated(
        // bottomSheet 영역에 가리지 않게 아래는 넉넉히
        padding: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 200),
        itemCount: todoList.length,
        // 함수에서 반환하는 코드(return)만 있다면 화살표 함수로
        separatorBuilder: (context, index) => SizedBox(height: 10),
        itemBuilder: (context, index) {
          Todo item = todoList[index];
          return TodoWidget(content: item.title, isDone: item.isDone);
        },
      ),

Update 구현

GestureDetector를 이용해 투두 아이템을 터치했을 때 isDone을 반대로 바꿔줌

      body: ListView.separated(
        // bottomSheet 영역에 가리지 않게 아래는 넉넉히
        padding: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 200),
        itemCount: todoList.length,
        // 함수에서 반환하는 코드(return)만 있다면 화살표 함수로
        separatorBuilder: (context, index) => SizedBox(height: 10),
        itemBuilder: (context, index) {
          Todo item = todoList[index];
          return GestureDetector(
            onTap: () {
              setState(() {
                item.isDone = !item.isDone;
              });
            },
            child: TodoWidget(content: item.title, isDone: item.isDone),
          );
        },
      ),

Delete 구현

투두 아이템을 길게 터치했을 때 삭제할 예정
하지만 사용자가 실수로 길게 터치할 때를 대비해서 팝업을 이용해 물어보고 처리

showCupertinoDialog 란?

iOS 스타일의 알림창(dialog) 을 띄워주는 함수
사용자가 실수로 삭제하거나 중요한 액션을 하기 전에 확인 여부를 물을 때 자주 사용됨
Flutter에서는 iOS 스타일을 위해 Cupertino 위젯군을 따로 제공

주요 속성

속성설명
context팝업도 내부적으로 Navigator가 관리하는 스택에 쌓여서 필요
builder실제로 보여줄 위젯을 리턴하는 함수 (CupertinoAlertDialog 반환)
barrierDismissible다이얼로그 바깥을 눌렀을 때 닫을지 여부 (false면 외부 터치로 안 닫힘)

CupertinoAlertDialog란?

iOS 스타일의 알림창 위젯
showCupertinoDialog 함수에서 이 위젯을 반환해 줘야 함

주요 속성

속성설명
title다이얼로그의 제목(주로 Text 위젯)
content다이얼로그 본문 (주로 Text 위젯)
actions사용자에게 보여줄 버튼들 (확인, 취소 등. CupertinoDialogAction 사용)
scrollController긴 콘텐츠를 스크롤할 수 있게 할 경우 사용

CupertinoDialogAction이란?

CupertinoAlertDialog 안의 actions에 들어가는 버튼
각각의 버튼에 대한 역할과 디자인을 iOS 스타일로 표현해줌

주요 속성

속성설명
child버튼 안에 표시될 위젯 (보통 Text)
onPressed버튼을 눌렀을 때 실행될 함수
isDefaultActioniOS에서 기본 액션 스타일로 표시할지 여부 (굵게 표시됨)
isDestructiveAction위험한 작업(삭제 등)일 경우 빨간색으로 표시됨

📝 Firebase

Firebase란?

Google에서 제공하는 모바일 및 웹 애플리케이션 개발 플랫폼
서버를 직접 구축하지 않아도 로그인, 데이터 저장, 알림 등을 손쉽게 구현할 수 있는 클라우드 백엔드 서비스

백엔드 서버란?

스마트폰으로 쇼핑몰 앱을 사용한다고 할 때

화면에 상품 이미지 → 프론트엔드

버튼을 눌러 장바구니에 담기
로그인을 하면 사용자 정보가 기억
결제하면 주문 내역이 저장
→ 백엔드

왜 Firebase가 필요한가?

직접 백엔드 서버를 구축하려면
서버 컴퓨터를 사고
데이터베이스 프로그램을 설치하고
로그인 기능을 직접 구현하고
보안과 트래픽도 모두 관리하고
이건 개인 개발자나 스타트업에게 큰 부담

Firebase는 "백엔드를 몰라도 앱을 만들 수 있게 해주는 도구"
특히 초보자, 스타트업, 빠른 MVP 개발에 최적화

Firebase의 주요 기능

기능설명
Firestore Database실시간으로 데이터를 동기화하는 클라우드 데이터베이스
Authentication이메일, Google, Facebook 등 다양한 로그인 방식 지원
Storage사진, 동영상 등 사용자 파일 안전하게 저장
Hosting앱을 빠르게 배포할 수 있는 웹 호스팅
Functions서버 코드도 클라우드에 작성 가능 (서버리스 백엔드)

📝 Firestore

Firestore란?

Firebase가 제공하는 클라우드 기반 NoSQL 데이터베이스
앱에서 생성되는 데이터를 실시간으로 저장하고 동기화할 수 있게 해줌

왜 Firestore가 필요한가?

구현한 투두앱에서 투두 목록은 앱이 종료되면 작성한 투두리스트가 사라짐
하지만 Firestore에 저장하면 앱을 꺼도, 다시 켜도, 다른 기기에서도 투두리스트가 그대로 유지

데이터베이스란?

데이터를 체계적으로 저장하는 장소, 일종의 디지털 창고

NoSQL이란?

기존의 데이터베이스는 “엑셀표”처럼 미리 정해진 구조로 데이터를 저장
반면, NoSQL은 더 유연한 구조로 데이터를 저장

기존 데이터베이스 방식

열(column)이 정해져 있어서 새로 추가하거나 누락된 값이 있으면 오류가 날 수 있음

번호할일완료여부
1플러터 공부false
2운동하기false
3강아지 산책true

NoSQL 방식

문서마다 다른 속성을 자유롭게 저장할 수 있어서, 상황에 맞게 유연하게 데이터 구조 구성 가능

문서: 1
{
	"할일": "플러터공부",
	"완료여부": "false"
}
문서: 2
{
	"할일": "운동하기",
	"완료여부": "false",
	"삭제일자": "2025-07-05",
	"삭제이유": "이미 건강함"
}
문서: 3
{
	"할일": "강아지 산책",
	"완료여부:" "true",
	"완료일자": "2025-05-05"
}

📝 Firebase 프로젝트 만들기

Firebase 프로젝트란?

Firebase 프로젝트는 여러 앱(iOS, Android, 웹 등)을 한 곳에서 통합 관리하고,
인증, 데이터베이스, 스토리지와 같은 Firebase의 다양한 서비스를 이용하기 위한 기본 단위
Firestore 데이터베이스 만들기 위해 만들어줘야함
보통 앱 하나당 하나씩 관리

flutterfire configure

Flutter 세팅하기

  1. firebase_core , cloud_firestore 패키지 추가
flutter pub add firebase_core cloud_firestore
  1. main.dart 에서 Firebase 패키지 구성 설정해주기
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_todo/firebase_options.dart';
import 'package:flutter_todo/home_page.dart';

void main() async {
	// 비동기 처리를 안전하게 할 수 있도록 준비하는 코드
	// runApp 전에 비동기 작업을 하려면 필수
  WidgetsFlutterBinding.ensureInitialized();
	// 현재 플랫폼(Android/iOS 등)에 맞는 Firebase 설정을 로드하고 앱에 초기화
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(MyApp());
}
  1. ios/Podfile 내 ios 최소버전 15로 맞추기 (Mac 사용자만)
    Firebase SDK는 네이티브 SDK를 사용하는데 15이상 버전부터 사용할 수 있게 되어있음
    iOS15 이상의 기기에서만 우리 앱을 사용할 수 있음
# Uncomment this line to define a global platform for your project
platform :ios, '15.0'
  1. android/app/build.gradle.kts
    안드로이드도 마찬가지로 네이티브 SDK를 사용하는데 23이상 버전부터 사용할 수 있게 되어있음
    android 23 이상의 기기에서만 우리앱을 사용할 수 있음
 minSdk = 23


공부 소감

내가 아래 쓴 부분이 날아가서 개 열받는다;;;;;;;;;;;;
하. ... 아무튼 firebase 맛 보기 했다..
쓴 내용 많은데 날아가서 진짜 도라방스
암튼 firebase 부분이 궁금해서 집 와서 강의를 더 들었다
그래서 11-1 day

0개의 댓글