Flutter 캠프 30일차

은성·2026년 1월 7일

Flutter 본캠프

목록 보기
32/57
post-thumbnail

Firebase

Firebase 셋팅 (3-5)

프로젝트 가져오는 명령어

  • flutterfire configure

core 추가해야 에러 사라짐

  • flutter pub add firebase_core

firebase 에서 fierstore 사용 할 수 있게 패키지 추가해줘야함

  • flutter pub add cloud_firestore

시뮬레이터 실행
(오류 날 경우 버전 확인 해보기)

  • 노란 부분에 적힌 버전과 하단 버전이 다를경우
    - ios > PodFile > 2번째 줄에 있는 "# platform :ios, '13.0'" 주석 해제 후 빨간색에 적힌 버전으로 수정 후 시뮬레이션 실행 (위 사진에서는 15.0)
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 런앱이 실행되기전 비동기 함수 사용해서 데이터 초기화 할 때 꼭 넣어줘야함
  await Firebase.initializeApp // initializeApp = 비동기이기에 awit 써줘야함
(options: DefaultFirebaseOptions.currentPlatform); //currentPlatform = 만들어진 firebase option 파일 , 각 플랫폼에 맡게 자동으로 옵션을 구현해줌
  runApp(ProviderScope(child: MyApp()));
}

Firebase CRUD 구현 (숙련 3-6 ~ 3-7)

CRUD


  • Create : 데이터 쓰기
    - 1) 파이어스토어 인스턴스 가지고 오기
    - 2) 컬렉션 참조 만들기
    - 3) 문서 참조 만들기
    - 4) 값 쓰기

  • Read : 특정 ID로 하나의 도큐먼트 가져오기
    - 1) 파이어베이스 파이어스토어 인스턴스 가져오기
    - 2) 컬렉션 참조 만들기
    - 3) 문서 참조 만들기
    - 4) 데이터 가지고오기

  • Update : 수정
    - 1) 파이어스토어 인스턴스 가져오기
    - 2) 컬렉션 참조 만들기
    - 3) 문서 참조 만들기
    - 4) 값을 업데이트 해주기 (set메서드=>update)
    docRef.set(data);
    => 업데이트 할 값 Map 형태로 넣어주기 : id에 해당하는 문서가 없을 때 새로 생성
    docRef.update(data;)
    => 업데이트 할 값 Map 형태로 넣어주기 : id에 해당하는 문서가 없을 때 에러 발생

  • Delete : 도큐먼트 삭제
    - 1) 파이어스토어 인스턴스 가져오기
    - 2) 컬렉션 참조 만들기
    - 3) 문서 참조 만들기
    - 4) 삭제

전체 코드

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_firebase_blog_app/data/model/post.dart';

class PostRepository {
  //
  Future<List<Post>?> getAll() async {
    try {
      // 1. 파이어스토어 인스턴스 가지고오기
      final firestore = FirebaseFirestore.instance;
      // 2. 컬렉션 참조 만들기
      final collectionRef = firestore.collection('posts');
      // 3. 값 불러오기
      final result = await collectionRef.get();

      final docs = result.docs;
      return docs.map((doc) {
        final map = doc.data();
        doc.id;
        final newMap = {'id': doc.id, ...map};
        return Post.fromJson(newMap);
      }).toList();
    } catch (e) {
      print(e);
      return null;
    }
  }

  // 1. Create : 데이터 쓰기
  Future<bool> insert({
    required String title,
    required String content,
    required String writer,
    required String imagUrl,
  }) async {
    try {
      // 1) 파이어스토어 인스턴스 가지고 오기
      final firestore = FirebaseFirestore.instance;
      // 2) 컬렉션 참조 만들기
      final CollectionRef = firestore.collection('posts');
      // 3) 문서 참조 만들기
      final docRef = CollectionRef.doc();
      // 4) 값 쓰기
      await docRef.set({
        'title': title,
        'content': content,
        'writer': writer,
        'imagUrl': imagUrl,
      });
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

  // 2. Read : 특정 ID로 하나의 도큐먼트 가져오기
  Future<Post?> getOne(String id) async {
    try {
      // 1) 파이어베이스 파이어스토어 인스턴스 가져오기
      final firestore = FirebaseFirestore.instance;
      // 2) 컬렉션 참조 만들기
      final collectionRef = firestore.collection('post');
      // 3) 문서 참조 만들기
      final docRef = collectionRef.doc(id);
      // 4) 데이터 가지고오기
      final doc = await docRef.get();
      return Post.fromJson({'id': doc.id, ...doc.data()!});
    } catch (e) {
      print(e);
      return null;
    }
  }

  // 3. Update : 수정
  Future<bool> update({
    required String id,
    required String writer,
    required String title,
    required String content,
    required String imageUrl,
  }) async {
    try {
      // 1) 파이어스토어 인스턴스 가져오기
      final firestore = FirebaseFirestore.instance;
      // 2) 컬렉션 참조 만들기
      final collectionRef = firestore.collection('post');
      // 3) 문서 참조 만들기
      final docRef = collectionRef.doc(id);
      // 4) 값을 업데이트 해주기 (set메서드=>update)
      // 업데이트 할 값 Map 형태로 넣어주기 : id에 해당하는 문서가 없을 때 새로 생성
      // docRef.set(data);
      // 업데이트 할 값 Map 형태로 넣어주기 : id에 해당하는 문서가 없을 때 에러 발생
      docRef.update({
        'writer': writer,
        'title': title,
        'content': content,
        'imageUrl': imageUrl,
      });
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

  // 4. Delete : 도큐먼트 삭제
  Future<bool> delete(String id) async {
    //
    try {
      // 1) 파이어스토어 인스턴스 가져오기
      final firestore = FirebaseFirestore.instance;
      // 2) 컬렉션 참조 만들기
      final collectionRef = firestore.collection('posts');
      // 3) 문서참조 만들기
      final docRef = collectionRef.doc(id);
      // 4) 삭제
      await docRef.delete();
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }
}

Firebase HomePage (ViewModel) 구현 (숙련 3-8)

import 'package:flutter_firebase_blog_app/data/model/post.dart';
import 'package:flutter_firebase_blog_app/data/repository/post_repository.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 1. 상태 클래스 만들기
// List<Post>
// 2. 뷰모델 만들기
class HomeViewModel extends Notifier<List<Post>> {
  
  List<Post> build() {
    getAllPoasts();
    return [];
  }

  void getAllPoasts() async {
    final postRepo = PostRepository();
    final posts = await postRepo.getAll();
    state = posts ?? [];
  }
}

// 3. 뷰모델 관리자 만들기
final homeViewModelProvider = NotifierProvider<HomeViewModel, List<Post>>(() {
  return HomeViewModel();
});

Firebase detailPage (ViewModel) 구현 (숙련 3-9)

  • 삭제, 연결 등 나옴
// 1. 상태 클래스 만들기
// post 객체 사용할거라 만들지 않음

// 2. 뷰모델 만들기
import 'package:flutter_firebase_blog_app/data/model/post.dart';
import 'package:flutter_firebase_blog_app/data/repository/post_repository.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class DetailViewModel extends Notifier<Post> {
  Post arg;
  DetailViewModel({required this.arg});

  
  Post build() {
    listenStream();
    return arg;
  }

  final postRepository = PostRepository();

  Future<bool> deletePost() async {
    return await postRepository.delete(arg.id);
  }

  void listenStream() {
    final stream = postRepository.postStream(arg.id);
    final streamSub = stream.listen((data) {
      if (data != null) {
        state = data;
      }
    });

    ref.onDispose(() {
      streamSub.cancel();
    });
  }
}

// 3. 뷰모델 관리자 만들기
final detailViewModelProvider = NotifierProvider.autoDispose
    .family<DetailViewModel, Post, Post>((arg) {
      return DetailViewModel(arg: arg);
    });

0개의 댓글