BaaS

  • Backend as a Service
  • 백엔드를 대신 서비스해주는 것 (백엔드가 불필요)

Firebase

  • Google이 제공하는 클라우드 기반의 개발 플랫폼
  • 앱 및 웹 애플리케이션 개발자들이 손쉽게 고품질의 앱을 구축하고 운영할 수 있도록 도와줌

[주요 기능]


  1. Realtime Database
    JSON 형태의 데이터를 실시간으로 동기화하고 공유할 수 있는 클라우드 호스팅 데이터베이스
    → 실시간으로 업데이트되는 데이터를 다수의 클라이언트 앱 간에 동기화할 수 있어 실시간 채팅, 게임 스코어 보드 등에 유용하게 사용됨
  2. Cloud Firestore
    유연하고 확장 가능한 NoSQL 문서 데이터베이스
    → 문서, 컬렉션, 필드 등 계층 구조로 데이터를 구성하며, 강력한 쿼리 기능을 제공하여 데이터를 쉽게 읽고 쓸 수 있음
  3. Authentication
    사용자 인증 시스템을 간단하게 구현할 수 있음
    → 이메일/비밀번호, 소셜 로그인(Google, Facebook 등), 기타 인증 방법을 지원하여 사용자 계정 관리를 용이하게 해줌
  4. Cloud Storage
    앱의 파일 저장과 관리를 위한 클라우드 스토리지 서비스
    → 사용자가 업로드한 파일(이미지, 동영상, 문서 등)을 보관하고 액세스할 수 있으며, 안전한 방식으로 파일을 처리함
  5. Hosting
    정적 웹 페이지 및 앱을 빠르고 안전하게 호스팅할 수 있음
    → Firebase의 글로벌 CDN(Content Delivery Network)을 활용하여 애플리케이션의 성능과 로딩 속도를 최적화할 수 있음
  6. Cloud Functions
    서버리스 컴퓨팅 플랫폼으로, JavaScript 또는 TypeScript를 사용하여 클라이언트 앱의 서버 사이드 로직을 작성할 수 있음
    → 클라우드 기능은 이벤트 기반으로 동작하며, 데이터베이스 업데이트, 사용자 인증, 알림 등과 같은 다양한 이벤트에 반응하여 실행될 수 있음
    → 새로운 사용자가 가입하면 이를 감지하여 환영 이메일을 자동으로 전송하는 등의 작업을 수행할 수 있음
  • 그 외에도
    • 실시간 알림 (Cloud Messaging)으로 사용자에게 푸시 알림을 보낼 수 있음
    • 앱 테스트 및 성능 모니터링 (Crashlytics, Performance Monitoring)을 수행할 수도 있음
    • 머신 러닝 모델을 개발하고 배포하기 위한 기능도 제공
    • 인증된 사용자에게 접근 권한을 부여하기 위한 세밀한 권한 관리 (Firebase Security Rules)도 가능

Firebase 연동

1. firebase 프로젝트 생성

  • 파이어베이스 콘솔 들어가서 프로젝트 추가

  • 프로젝트 이름 넣기

  • 계정 선택 후 프로젝트 만들기 클릭

  • 파이어베이스 프로젝트 생성 완료

2. firebase CLI 설치

  • 생성한 프로젝트에서 플러터 아이콘 클릭

  • 들어가서 CLI 설치
    - install firebase cli

  • 사용하는 운영체제에 맞춰서 설치하십시오

  • 설치 후 실행 시 cmd창 켜짐
    - Allow Firebase to collect CLI and Emulator Suite usage and error reporting information? (y/n) : y/n 중 아무거나 입력해도 상관업승ㅁ

  • 입력하면 구글 로그인 창 뜨고 로그인 완료하면 사진처럼 완료 문구 보여줌

  • 완료 후 firebase -h 입력 -> 명령어들 설명해주면 설치 잘된거
  • 로그인 확인 : firebase login:list
    - 메일 주소 보이면 로그인도 잘된거

3. 플러터 프로젝트에서

  • 안드로이드 스튜디오 하단 터미널 클릭해서 터미널 열기

  • 복사해서 터미널에 붙여넣으면 알아서 잘 설정해줌

  • 얘도 붙여넣기

  • 에러뜸;;
    flutterfire : 'flutterfire' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다. 이름이 정확한지 확인하고 경로가 포함된 경우 경로가 올바른지 검 증한 다음 다시 시도하십시오.

  • flutterfire 해결 (이것저것 뭔가를 많이 햇더니 어케 해결햇는지는 까먹엇어요)

    다시 저 에러를 만난다면... 쩝... 믿는다! 미래의 나!

  • 추가 에러 (flutterfire configure시 발생)

i Found 0 Firebase projects.
FirebaseCommandException: An error occured on the Firebase CLI when attempting to run a command.
COMMAND: firebase --version 
ERROR: The FlutterFire CLI currently requires the official Firebase CLI to also be installed, see https://firebase.google.com/docs/cl
i#install_the_firebase_cli for how to install it.
  • 위 에러는 node.js 설치 후https://nodejs.org.ko
    터미널에 npm install -g firebase-tools 입력

  • 하고 다시 flutterfire configure 복붙
    드디어;;;;

  • 안드, ios만 설정할거임

  • lib > firebase_options.dart가 생겻어요~

  • +firebase_core 패키지도 설치하기 pub.dev - firebase_core

4. 코드짤때

  • firebase_options.dart의 13~15번 라인 복사

  • main.dart에 붙여넣기

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();  // 메인 함수에 비동기 함수 있으면 추가해줘야함
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

Cloud Firestore

  • pub.dev - cloud_firestore
  • NoSQL 방식의 데이터베이스 시스템으로 사용됨
  • CRUD 방식으로 데이터를 손쉽게 다룰 수 있다
  • 사옹하기 전에 다음 코드를 반드시 포함한다
    WidgetsFlutterBinding.ensureInitialized();
    Firebase.initializeApp();

Firestore 데이터베이스 만들기

  • 파이어베이스 콘설 > 프로젝트 > 빌드 > Firestore database > 데이터베이스 만들기

  • 일단 테스트모드로

  • 데이터베이스 위치는 서울로 진행

  • 짜잔

  • 컬렉션: 데이터가 모여있는 하나의 저장공간이라고 생각하면 됨

  • 필드 추가하고 저장
    - 문서 아이디는 자동ID 눌러서 자동생성 가능

  • 짜잔

CRUD

  • Create: 만들고
  • Read: 읽고
  • Update: 수정하고
  • Delete: 삭제까지

Read

  • 데이터 읽어오기

  • 해당 컬렉션의 문서들을 가져온다

    FirebaseFirestore.instance.collection(컬렉션명).get();
  • 해당 컬렉션의 선택 문서 하나만 가져온다

    FirebaseFirestore.instance.collection(컬렉션명).doc(문서명).get();

    문서 ID:

  • 해당 컬렉션에 필터를 걸고 해당되는 문서만 가져오기
    FirebaseFirestore.instance.collection(컬렉션명).where(, isEqualTo:);

코드 작성

  • read_page.dart
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/material.dart';
    
    class ReadPage extends StatefulWidget {
      const ReadPage({Key? key}) : super(key: key);
    
      
      State<ReadPage> createState() => _ReadPageState();
    }
    
    class _ReadPageState extends State<ReadPage> {
    
      var instance = FirebaseFirestore.instance;
      List items = [];
    
      readFromCloudFireStore() async {
        var res = await instance.collection('memo').get();
        setState(() {
          items = res.docs.map((e) => e.data()).toList();
        });
      }
    
      getDocument(String documentId) async {
        var res = await instance.collection('memo').doc(documentId).get();
        print(res.data());
      }
    
      readFinishedDocuments() async {
        var res = await instance.collection('memo').where('isFinished', isEqualTo: true).get();
        print(res.docs);
        print(res.size);
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TextButton(
                  onPressed: readFromCloudFireStore,
                  child: Text('가져오기'),
                ),
                TextButton(
                  onPressed: () {
                    getDocument('mbJD2cLGnswxos5BoOMD');
                  },
                  child: Text('하나만 가져오기'),
                ),
                TextButton(
                  onPressed: () {
                    readFinishedDocuments();
                  },
                  child: Text('finished만 가져오기'),
                ),
                if (items.isNotEmpty) ...items.map((e) => Text(e['title'])).toList()
              ],
            ),
          ),
        );
      }
    }

Create

  • 데이터를 생성
  • DocId 자동 (unique auto-generated)
    FirebaseFirestore.instance
    	.collection(컬렉션명)
    	.add({'key': value});
  • 지정 DocId (set)
    FirebaseFirestore.instance
    	.collection(컬렉션명)
    	.doc(지정이름)
    	.set({'key': value});
    • 이미 존재하는 id면 SetOption(merge: true) 값을 주어서 새로운 값으로 덮어씌울 수 있음

코드 작성

  • create_page.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class CreatePage extends StatefulWidget {
  const CreatePage({Key? key}) : super(key: key);

  
  State<CreatePage> createState() => _CreatePageState();
}

class _CreatePageState extends State<CreatePage> {

  var instance = FirebaseFirestore.instance;

  createDocument(String title) async {
    await instance
      .collection('memo')
      .add({'title': title, 'isFinished': false});
  }

  createDocumentById(String docId, String title) async {
    await instance
      .collection('memo')
      .doc(docId)
      .set({'title': title, 'isFinished': false});
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextButton(
              onPressed: () {
                createDocument('햄버거먹기');
              },
              child: Text('문서 추가'),
            ),
            TextButton(
              onPressed: () {
                createDocumentById('123456789', '밥먹기');
              },
              child: Text('문서 추가(지정 아이디)'),
            ),
          ],
        ),
      ),
    );
  }
}

Update

  • 데이터를 수정
    FirebaseFirestore.instance
    	.collection(컬렉션명)
    	.doc(지정이름)
    	.update({'key': value});

코드 작성

  • update_page.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class UpdatePage extends StatefulWidget {
  const UpdatePage({Key? key}) : super(key: key);

  
  State<UpdatePage> createState() => _UpdatePageState();
}

class _UpdatePageState extends State<UpdatePage> {

  var instance = FirebaseFirestore.instance;

  updateDocument(String docId, Map<String, dynamic> data) {
    instance.collection('memo').doc(docId).update(data);
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextButton(
              onPressed: () {
                updateDocument('123456789', {'isFinished': true});
              },
              child: Text('문서 수정'),
            ),
          ],
        ),
      ),
    );
  }
}

Delete

  • 데이터를 삭제
    FirebaseFirestore.instance
    	.collection(컬렉션명)
    	.doc(지정이름)
    	.delete();

코드 작성

  • delete_page.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class DeletePage extends StatefulWidget {
  const DeletePage({Key? key}) : super(key: key);

  
  State<DeletePage> createState() => _DeletePageState();
}

class _DeletePageState extends State<DeletePage> {
  var instance = FirebaseFirestore.instance;

  deleteDocument(String docId) {
    instance.collection('memo').doc(docId).delete();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextButton(
              onPressed: () {
                deleteDocument('123456789');
              },
              child: Text('문서 삭제'),
            ),
          ],
        ),
      ),
    );
  }
}

  • main.dart
    import 'package:firebase_core/firebase_core.dart';
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import '../../../firebase_options.dart';
    import 'create_page.dart';
    import 'delete_page.dart';
    import 'read_page.dart';
    import 'update_page.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();  // 메인 함수에 비동기 함수 있으면 추가해줘야함
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
        return GetMaterialApp(
          home: Scaffold(
            body: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TextButton(
                  onPressed: () {
                    Get.to(() => CreatePage());
                  },
                  child: Text('create'),
                ),
                TextButton(
                  onPressed: () {
                    Get.to(() => ReadPage());
                  },
                  child: Text('read'),
                ),
                TextButton(
                  onPressed: () {
                    Get.to(() => UpdatePage());
                  },
                  child: Text('update'),
                ),
                TextButton(
                  onPressed: () {
                    Get.to(() => DeletePage());
                  },
                  child: Text('delete'),
                ),
              ],
            ),
          ),
        );
      }
    }

  • 또 에러

uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:cloud_firestore]

android > app > build.gradle

minSdkVersion flutter.minSdkVersionminSdkVersion 21 수정 (19로 수정해도 에러낫음)


34일차 끝~

빨간 글씨들을 너무 많이 봐서 어질어질하네요
그래도 역시 파이어베이스... 재밋습니다... 굿굿...

과제........언제하지

profile
우와재밋다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN