2023. 4. 7. 00:24ㆍDevelopers 공간 [Shorts]/Frontend
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew,
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter
- Module Bundler : React, Webpack, Parcel
B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS
C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight
1. What? (현상)
Firebase는 BaaS(Backend-as-a-Service) 플랫폼입니다. 개발자가 모바일, 웹 애플리케이션 등을 쉽게 생성하고 실행하고 확장할 수 있도록 돕습니다. 또한 실시간 데이터베이스, 인증, 스토리지, 호스팅 및 기타 기능을 제공하며 모두 단일 플랫폼에서 관리되도록 돕습니다.
기본적으로 Firebase 프로젝트를 만들고 앱을 등록하는 기능을 제공하는 것과 더불어, 기타 기능은 ①빌드, ②출시 및 모니터링, ③참여 로 나뉘어 제공됩니다. 기타 서비스 중 우리가 관심있어 하는 것을 예로 들면 실시간 데이터베이스, Firestore, Storage, Cloud Functions 등은 ①빌드에 포함되어있으며, Analytics는 ③참여에 포함되어 있습니다.
자세한 내용은 아래 링크에서 확인할 수 있습니다.
https://firebase.google.com/?hl=ko
-----------------------------------------------------------------------------------------------------
<Firebase의 Storage에 대해서>
Firebase용 Storage는 Cloud Storage와 Cloud Firebase가 있습니다. 먼저, Cloud Storage는 사진, 동영상 등의 사용자 제작 콘텐츠를 저장하고 제공해야 하는 앱 개발자를 위해 만들어진 파일 스토리지 시스템입니다. 또한 Cloud Firestore는 대규모로 확장 가능한 실시간 NoSQL 데이터베이스입니다. 즉, 실시간 클라이언트 애플리케이션 간에 데이터의 동기화를 유지하고 모바일 및 웹에 대한 오프라인 지원을 제공해 네트워크 지연 시간이나 인터넷 연결에 상관없이 원활하게 반응하는 앱을 개발하기 위해 사용할 수 있는 데이터베이스입니다.
소규모 스타트업은 Firebase의 Firestore와 storage를 쓰는 것이 유리하다는 의견이 있습니다. 소규모 스타트업의 경우 1~2인의 풀 스택 개발자가 서버 인프라 관리와 클라이언트 개발 이후에 VoC(Voice of Customer)를 반영한 구조을 식속하게 대응하기는 어렵습니다. 따라서 Firebase를 이용해 Database, storage, Auth, Analytics까지 한번에 해결할 수 있는 것입니다. 가격 책정 면에서도 유리하고, Firestore의 경우 Socket으로 연결되어 실시간 서비스를 구축하기 좋고 Storage의 경우 클라이언트 단에서 바로 파일을 올리기 쉽기 떄문에 좋습니다.
** flutter_uploader 플러그인 : 백그라운드 업로드를 수행하는 플러그인인데, firebase를 integration하기 쉽습니다.
<Firebase의 청구방식 예제 : Firestore>
Cloud Firestore 사용량에 대한 청구 방식을 이해하면서 사용량 수준별 비용에 대해 이해해보도록 합니다.
- 상황 예시
- 2명 이상의 참여자와 채팅을 시작할 수 있는 채팅 앱
- 일일 활성 사용자 수(DAU)는 전체 앱 설치의 10%이라고 가정합니다.
** Active User(활성 사용자) : 유저가 접속해서 활동하는지에 대한 수치입니다. 웹분석에서는 Visit(방문수), Visitor(방문자수)등의 용어로 측정하고, 앱분석에서는 DAU(Daily Active User), WAU(Weekly Active User), MAU(Monthly Active User)로 측정합니다.
** DAU(Daily Active User) : 기기마다의 UUID를 통해 하루동안 접속한 유저의 수를 파악하는 것입니다. - 문서 크기는 비교적 작다고 가정합니다. (문서당 0.25KB~1KB를 전송해 디스크에 0.75KB~3KB 저장)
- 위 데이터는 3개월 동안만 저장된다고 가정합니다.
- 사용자 작업별 청구 사용량
- 사용자는 대개 앱에서 다음과 같은 일반적인 작업을 수행합니다.
- 채팅 목록 보기: 가장 최근에 게시된 메시지 순으로 정렬된 채팅 목록 확인 가능
- 채팅 메시지 읽기: 채팅을 선택하고 최근 채팅 메시지를 읽기 기능
- 채팅 메시지 보내기: 사용자가 채팅 메시지를 보내는 것이 가능
- 예상작업량
- 읽기 : 일일 사용자별 읽기 80회
- 쓰기: 일일 사용자별 쓰기 20회
- 네트워크 egress : 일일 사용자별 20KB
** Ingress : 외부로부터 서버 내부로 유입되는 네트워크 트래픽
** egress : 서버 내부에서 외부로 나가는 네트워크 트래픽 - 저장소 : 일일 사용자별 15KB
- 사용자는 대개 앱에서 다음과 같은 일반적인 작업을 수행합니다.
- 결과 (읽기/쓰기 비용 + 네트워킹/저장소 비용)
- 소규모 (앱설치 50,000건 : 일일 활성사용자 5,000명): : $12.14/월
- 중규모 (앱설치 1,000,000건 : 일일 활성사용자 100,000명) : $292.02/월,
- 대규모 (앱설치 10,000,000건 : 일일 활성사용자 1,000,000명) : $2951.52/월
-----------------------------------------------------------------------------------------------------
이번 글에서는 Flutter에 기본적으로 플랫폼을 추가하고 Analytics를 사용하는 방법을 먼저 소개하려고합니다.
Firebase 프로젝트란 모든앱과 모든프로젝트에 provisioning 된 리소스와 서비스를 위한 container입니다.
** Provisioning : IT 인프라를 생성하고 설정하는 프로세스로, 서버&애플리케이션&네트워크 구성&스토리지&엣지 기기 등을 배포하는 과정에서 초기 단계입니다. 예를 들어, Server Provisioning이란 physical hardware를 설정하고 OS와 네트워크 등을 설정하는 과정을 provisioning이라고 합니다. 또한 Service Provisioning 이란 사용자를 위한 데이터 및 엑세스 제한을 부여하고 정리하는 과정을 의미합니다.
하나의 프로젝트에는 여러개의 앱을 등록할 수 있으며, 동일 백엔드를 공유하며 리소스와 서비스를 공유할 수 있는 단위입니다.
-----------------------------------------------------------------------------------------------------
<Firebase와 Google Cloud(GCP)의 관계>
하나의 Firebase 프로젝트에는 Google Cloud(GCP) 프로젝트가 자동으로 생성되며, 나중에 다른 GCP 프로젝트를 추가할 수도 있습니다.
Google Cloud는 클라우드 컴퓨팅 서비스 제품군으로, Google 인프라 (컴퓨팅, 스토리지, 네트워킹, 데이터 분석, 머신러닝)를 구성 가능한 서비스 형태로 공개적으로 제공합니다. 주로 백엔드 및 서버 측 개발자가 사용하며, Google의 핵심 인프라, 데이터 분석, 머신러닝을 활용하여 소프트웨어를 빌드하는 데 사용합니다.
Firebase는 Google의 모바일 개발 플랫폼으로, 앱을 빌드하고 사용자층을 확대하는데 사용합니다. 웹 및 모바일의 클라이언트 측 앱 개발자가 사용하며, 새 모바일 앱 빌드, 새 기능으로 기존 앱 보강, 잠재고객 증가 등을 위해 사용합니다.
두 프로젝트 모두 Cloud Firestore, Cloud Functions, Cloud Storage라는 세 가지 제품을 공유하며, 세 제품 모두 사실은 Google Cloud 제품이지만 Firebase를 통해 클라이언트 측 개발자에게 제공합니다. 서버 SDK(Google Cloud) 및 클라이언트 SDK(Firebase)에서 동일하게 데이터에 액세스 가능하기 때문에 프런트엔드팀과 백엔드팀이 협력하여 작업할 수 있습니다.
-----------------------------------------------------------------------------------------------------
2. Why? (원인)
- X
3. How? (해결책)
- 환경 셋팅1 : 시스템에 firebase-tools를 설치하고 로그인합니다. 메일 계정은 Gmail로 로그인해줍니다.
npm install -g firebase-tools
firebase login
- 환경 셋팅2 :
- 링크(https://firebase.google.com/)에 들어가 아래와 같이 프로젝트를 먼저 만들어 줍니다.
- 그 다음 하기 명령어를 통해 프로젝트의 시스템에 flutterfire_cli를 설치합니다.
- 그 다음 내 Flutter 프로젝트 Terminal에 들어가 하기 flutterfire 명령어를 통해, 내 프로젝트와 firebase를 연결해줍니다.
** 위 방법이 아니라, 직접 프로젝트에 android/ios/macOS/web 등을 셋팅해주는 방법도 있지만 추천드리지 않습니다. 참조하시려면 해당링크를 참조하세요(https://firebase.flutter.dev/docs/manual-installation)
flutter pub global activate flutterfire_cli
flutterfire configure
# Result Files
# android/app/google-services.json
# ios/Runner/GoogleService-Info.plist
# lib/firebase_options.dart
- 환경 셋팅3 : 내 Flutter 프로젝트에서 firebase_core 라이브러리를 설치하고 import 해줍니다.
- 아래의 firebase_options.dart 파일은 위 과정을 거치면 저절로 생깁니다.
- 또한 아래와 같이 void main(){} 함수에서 미리 셋팅을 해주어야합니다.
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
그럼 환경셋팅이 끝났으니, flutter에 Analytics를 구현하는 방법을 두가지로 나누어 살펴보겠습니다.
시작하기에 앞서 설치는 아래와 같이 진행합니다.
flutter pub add firebase_analytics
flutterfire configure
- 코드 셋팅1 : 기본적인 기능을 가진 FirebaseAnalytics 오브젝트를 선언합니다.
- FirebaseAnalytics : API를 사용하기 위한 Objet입니다. 이것을 활용해 기본적인 API를 보낼 수 있습니다.
import 'package:firebase_analytics/firebase_analytics.dart';
// Declare : Will be Used
static FirebaseAnalytics analytics = FirebaseAnalytics.instance;
// Setting ID
analytics.setUserId('ID@kakao.com');
// Sending API
analytics.logLogin(loginMethod: 'Kakao');
analytics.logSignUp(signUpMethod: 'Kakao');
analytics.logAddToCart(
itemId: 'ID',
itemName: 'NAME',
itemCategory: 'CATEGORY',
quantity: 3);
}
analytics.logViewItem(
itemId: 'ID',
itemName: 'NAME',
itemCategory: 'CATEGORY',
price: 3000.0,
currency: 'won');
}
analytics.logSearch(searchTerm: 'SEARCHTERM');
-----------------------------------------------------------------------------------------------------
<Log 데이터를 처리하기 위한 명령어>
FirebaseAnalytics 오브젝트 중 데이터를 전체적으로 처리하기 위한 API입니다.
- resetAnalyticsData() → Future<void>
앱에 대한 analytics data를 모두 clear하고, 앱의 instance ID를 초기화합니다. - setAnalyticsCollectionEnabled(bool enabled) → Future<void>
analytics를 모으는 것이 가능하도록 셋팅 - setConsent({bool? adStorageConsentGranted, bool? analyticsStorageConsentGranted}) → Future<void>
유저의 동의 상태를 셋팅합니다. default는 adStorageConsentGranted와 analyticsStorageConsentGranted 모두 true입니다 - setCurrentScreen({required String? screenName, String screenClassOverride = 'Flutter', AnalyticsCallOptions? callOptions}) → Future<void>
현재 앱에서의 visual context인 screen의 이름을 셋팅합니다. - setDefaultEventParameters(Map<String, Object?>? defaultParameters) → Future<void>
자동인 것을 포함해 SDK에 logging된 모든 이벤트에 대한 파라미터를 셋팅합니다. - setSessionTimeoutDuration(Duration timeout) → Future<void>
현재 session에서 비활성화하기 위한 timeout duration을 셋팅합니다. - setUserId({String? id, AnalyticsCallOptions? callOptions}) → Future<void>
유저의 ID property를 셋팅합니다. - setUserProperty({required String name, required String? value, AnalyticsCallOptions? callOptions}) → Future<void>
유저의 Property를 셋팅합니다.
-----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------
<Log를 보내기 위한 명령어>
FirebaseAnalytics 오브젝트를 활용한 기본적인 API입니다. 아래 링크를 참조하시면 자세히 알 수 있으며, 아래 내용은 23/04/23 기준 최신 API입니다.
https://support.google.com/analytics/answer/9267735?hl=ko
- logAddPaymentInfo({String? coupon, String? currency, String? paymentType, double? value, List<AnalyticsEventItem>? items, AnalyticsCallOptions? callOptions}) → Future<void>
- logAddShippingInfo({String? coupon, String? currency, double? value, String? shippingTier, List<AnalyticsEventItem>? items, AnalyticsCallOptions? callOptions}) → Future<void>
- logAddToCart({List<AnalyticsEventItem>? items, double? value, String? currency, AnalyticsCallOptions? callOptions}) → Future<void>
- logAddToWishlist({List<AnalyticsEventItem>? items, double? value, String? currency, AnalyticsCallOptions? callOptions}) → Future<void>
- logAdImpression({String? adPlatform, String? adSource, String? adFormat, String? adUnitName, double? value, String? currency, AnalyticsCallOptions? callOptions}) → Future<void>
- logAppOpen({AnalyticsCallOptions? callOptions}) → Future<void>
- logBeginCheckout({double? value, String? currency, List<AnalyticsEventItem>? items, String? coupon, AnalyticsCallOptions? callOptions}) → Future<void>
- logCampaignDetails({required String source, required String medium, required String campaign, String? term, String? content, String? aclid, String? cp1, AnalyticsCallOptions? callOptions}) → Future<void>
- logEarnVirtualCurrency({required String virtualCurrencyName, required num value, AnalyticsCallOptions? callOptions}) → Future<void>
logEcommercePurchase({String? currency, double? value, String? transactionId, double? tax, double? shipping, String? coupon, String? location, int? numberOfNights, int? numberOfRooms, int? numberOfPassengers, String? origin, String? destination, String? startDate, String? endDate, String? travelClass}) → Future<void>- logEvent({required String name, Map<String, Object?>? parameters, AnalyticsCallOptions? callOptions}) → Future<void>
- logGenerateLead({String? currency, double? value, AnalyticsCallOptions? callOptions}) → Future<void>
- logJoinGroup({required String groupId, AnalyticsCallOptions? callOptions}) → Future<void>
- logLevelEnd({required String levelName, int? success, AnalyticsCallOptions? callOptions}) → Future<void>
- logLevelStart({required String levelName, AnalyticsCallOptions? callOptions}) → Future<void>
- logLevelUp({required int level, String? character, AnalyticsCallOptions? callOptions}) → Future<void>
- logLogin({String? loginMethod, AnalyticsCallOptions? callOptions}) → Future<void>
- logPostScore({required int score, int? level, String? character, AnalyticsCallOptions? callOptions}) → Future<void>
logPresentOffer({required String itemId, required String itemName, required String itemCategory, required int quantity, double? price, double? value, String? currency, String? itemLocationId}) → Future<void>- logPurchase({String? currency, String? coupon, double? value, List<AnalyticsEventItem>? items, double? tax, double? shipping, String? transactionId, String? affiliation, AnalyticsCallOptions? callOptions}) → Future<void>
logPurchaseRefund({String? currency, double? value, String? transactionId}) → Future<void>- logRefund({String? currency, String? coupon, double? value, double? tax, double? shipping, String? transactionId, String? affiliation, List<AnalyticsEventItem>? items}) → Future<void>
- logRemoveFromCart({String? currency, double? value, List<AnalyticsEventItem>? items, AnalyticsCallOptions? callOptions}) → Future<void>
- logScreenView({String? screenClass, String? screenName, AnalyticsCallOptions? callOptions}) → Future<void>
- logSearch({required String searchTerm, int? numberOfNights, int? numberOfRooms, int? numberOfPassengers, String? origin, String? destination, String? startDate, String? endDate, String? travelClass, AnalyticsCallOptions? callOptions}) → Future<void>
- logSelectContent({required String contentType, required String itemId}) → Future<void>
- logSelectItem({String? itemListId, String? itemListName, List<AnalyticsEventItem>? items, AnalyticsCallOptions? callOptions}) → Future<void>
- logSelectPromotion({String? creativeName, String? creativeSlot, List<AnalyticsEventItem>? items, String? locationId, String? promotionId, String? promotionName, AnalyticsCallOptions? callOptions}) → Future<void>
logSetCheckoutOption({required int checkoutStep, required String checkoutOption}) → Future<void>- logShare({required String contentType, required String itemId, required String method}) → Future<void>
- logSignUp({required String signUpMethod}) → Future<void>
- logSpendVirtualCurrency({required String itemName, required String virtualCurrencyName, required num value}) → Future<void>
- logTutorialBegin() → Future<void>
- logTutorialComplete() → Future<void>
- logUnlockAchievement({required String id}) → Future<void>
- logViewCart({String? currency, double? value, List<AnalyticsEventItem>? items, AnalyticsCallOptions? callOptions}) → Future<void>
- logViewItem({String? currency, double? value, List<AnalyticsEventItem>? items}) → Future<void>
- logViewItemList({List<AnalyticsEventItem>? items, String? itemListId, String? itemListName}) → Future<void>
- logViewPromotion({String? creativeName, String? creativeSlot, List<AnalyticsEventItem>? items, String? locationId, String? promotionId, String? promotionName}) → Future<void>
- logViewSearchResults({required String searchTerm}) → Future<void>
----------------------------------------------------------------------------------------------------
- 코드셋팅2 : observer를 활용해서 analytics를 활용하는 방법입니다. (사용해본 적은 없습니다)
- FirebaseAnalyticsObserver : 해당하는 MoalRoute의 변화에 따라서 Firebase Analytics에 event를 보내기 위한 observer입니다.
** Navigator.of(context) : .push() 혹은 .pushNaed() 함수를 통해 Route간 이동할 때 사용된다. (MaterialApp의 속성중 routes를 활용해 Route Table을 등록해두고 사용합니다.)
** ModalRoute.of(context) : Navigator.of(context).pushNamed()함수를 통해 argument 값이 전달되어었을 때, ModalRoute.of(context).setting.arguments 를 활용해 데이터를 전달받을 때 사용합니다.
- FirebaseAnalyticsObserver : 해당하는 MoalRoute의 변화에 따라서 Firebase Analytics에 event를 보내기 위한 observer입니다.
// Declare
static FirebaseAnalyticsObserver observer = FirebaseAnalyticsObserver(analytics: analytics);
// HowtoUse : didChangeDependencies()
widget.observer.subscribe(this, ModalRoute.of(context)! as PageRoute);
// HowtoUse : dispose()
widget.observer.unsubscribe(this);
https://github.com/firebase/flutterfire
https://brunch.co.kr/@second-space/5
https://warmdeveloper.tistory.com/29
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=naminu123&logNo=221454614803
https://firebase.google.com/docs/flutter/setup?hl=ko&platform=ios
https://pub.dev/documentation/firebase_analytics/latest/
예시
https://firebase.google.com/docs/flutter/setup?hl=ko&platform=ios
https://firebase.google.com/docs/analytics/get-started?platform=flutter&hl=ko
'Developers 공간 [Shorts] > Frontend' 카테고리의 다른 글
[Flutter] 앱의 이름, ID, 아이콘 변경하기 (1) | 2023.05.06 |
---|---|
[Flutter] Flutter에 안드로이드폰을 연결해주기 (0) | 2023.05.06 |
[Flutter] Geolocator 사용하기 (0) | 2023.04.03 |
[Flutter] iOS 개발 시 나오는 다양한 ID 정리 (+signing 개념) (0) | 2023.04.02 |
[Flutter] Platform 정보를 확인하기 위한 방법 정리 (0) | 2023.04.02 |