이번 블로그 포스팅 시리즈에서는 플러터와 함께 Firebase Cloud Messaging (FCM) 토큰을 사용하여 웹 알림을 구현하는 과정을 기록해보겠습니다.
[TL;DR] 들어가며
프론트엔드 공부 필요성에 대해서
브라우저가 단순 페이지를 표시하는 것을 넘어서 일종의 미들웨어처럼 기능하고 있다 해도 과언이 아닐 정도로 굉장히 웹 기술이 고도화되고 있는 것 같다는 생각이 듭니다. 또 서버리스가 대세가 되면서 요즘 웹 개발쪽도 전통적인 3 티어 구조보다는 웹과 모바일 + 인프라 구조로 달라지고 있는 추세도 보이구요.
그래서 결론적으로는 뭔가 백엔드와 프론트엔드 영역 구분이 무의미해지고 있다는 생각이 들었어요.
프론트엔드도 공부해보고 싶었고 특히 만들고 싶은 프로젝트가 있으면 필수 역량인 것 같아서 공부하게 되었습니다.
최근에는 Next.JS, 리액트 네이티브, Flutter 에 대한 이야기도 많이 들려서 관심이 많이 생기더라구요!
그 중 최근에는 플러터를 공부하고 있습니다.
기존 프론트엔드 경험 관련
일단 프론트엔드 관련 경험해 본 건 1년전쯤 제가 첫 개발 취준을 했던 시절에 꽤 규모있는 스타트업에 운좋게 프론트엔드 서류를 통과하고 나서 과제 전형으로 Next.Js 프레임워크를 사용해서 REST API 로 소통하는 간단한 커뮤니티 게시판을 구현했었습니다. 그때 처음 프론트를 해봤었는데도 일주일 시간 내로 추가 구현까지 했었고, 최종 합격까지 갔었어요! (자랑입니다! ㅎㅎ 근데 역시 운도 좋았던 것 같아요.)
그 외 프론트에 대한 지식은 전무한 상태입니다.
플러터 구현 관련
알림과 화면 구현은 2주 전에 작업 완료했고 그때 구현까지는 2-3일 정도 걸렸습니다.
당시 그 과정을 개인 문서로 과정을 기록해두었는데, 이번 포스팅은 그 타임라인대로 차근차근 그때의 의식의 흐름을 팔로우업 하는 방식으로 진행해볼까 합니다.
서버에서 fcm 토큰을 가지고 알림을 발송하는 구현은 해봤지만 프론트 쪽 알림 발송 원리를 잘 모르는 상태에
플러터, dart 언어도 모두 처음 상태로 무대뽀로 시작했었습니다.
처음에는 IDE 에서 제공하는 기본 스켈레톤 코드를 베이스로 미디엄 블로그 보고 무지성으로 따라 했었는데 에러가 발생해서 안되더라구요;; (아마 플러터 버전 호환 이슈가 아닐까 생각하고 있어요)
그래서 프로젝트 싹다 초기화하고..쓴 고배를 맛보고 나서 처음부터 공식문서 기반으로 구현했습니다.
당시 백그라운드 알림 기능과 웹브라우저 화면에서 firebase 를 통해 알림 메시지 객체가 들어오면 화면 리스트에 추가되는 기능을 구현했었는데요.
이번 포스팅 시리즈에서는 복습 겸 토스트 알림 화면까지 기능 고도화 해보고 더 자세히 이론도 공부해보고 싶어요.
또 전체적으로 갈피가 잡혔으니 그때 참고했었던 해당 미디엄글이 왜 구체적으로 안됐는지도 함께 찾아보면 재밌을 것 같아요.
플러터 소감
플러터 해보면서 느꼈던 부분이, Flutter 는 웹에 정~말 불친절하구나...랑 정말 엄청나게 깔끔한 경험을 선사해주는구나를 느꼈습니다.
위젯이라는 개념이 정말 흥미로웠어요. 백엔드로 치면 서버리스 같은 느낌이라 해야할까, 모든걸 알아서 처리해주지만 그만큼 저에게 책임과 권한이 적다..라는 인상을 받았습니다. 그리고 정말 매력적인 기술이고 이렇게 멀티 플랫폼으로 구현된다는게 신기해요! 그런데 웹도 되는건데..JS 비중이 정말 적어서 대체 어떻게 JS - 브라우저로 빌드 & 렌더링해준거지? 신기했습니다.
잠깐 찾아보니 이해를 모두 한건 아니지만, 원리가 정말 특이해요!
Flutter architectural overview | Flutter
booiljung.github.io/technical_articles/flutter/hummingboard_building_flutter_for_the_web.html
정말 독특한만큼 끌리는 마성의 친구입니다.
공식문서도 fcm token 개념이 부족한 상태에서 보니까 처음에는 어려웠고
또 쓰다보니까 생각난건데 플러터 문서가 웹한테 넘 불친절해요!!! ㄱ-
fcm 알림 관련 서비스 워커 js 파일도 버전 9부터는 ts 로 쓴 다음에 빌드해라는 걸 공식문서에 찾아보기도 힘들게 적어둬서 삽질했었어요;; 아무튼 이런 경험들은 포스팅해보면서 정리 겸 차차 써볼게요.
Firebase, 푸시알림에 대해서, WEB API 에 대해서도 많이 알게 되었어요. 많이 배우고 정말 재밌게 작업했습니다!
각설하고,
제가 이 과정을 거치면서 어떤 문제를 마주쳤고 어떻게 해결했는지 또 어떤 새로운 것을 배웠는지 등을 적어 나갈 예정이니 읽어주시면 감사하겠습니다. 언제든 피드백은 환영입니다.
- 기본 환경은 M1 맥북 에어로 진행하였습니다.
환경 세팅하기: 플러터 설치하는 과정 의식의 흐름
Flutter 공식문서를 들어가서 Get Started 문서를 확인해 줍니다.
Choose your development platform to get started | Flutter
공식문서에서 작성된 하드웨어와 소프트웨어 (맥북 실리콘 칩 ARM 인 경우 인텔 칩과 호환되게 하는 로제타 설치) 조건을 충족해줍니다.
기본적인 개발 툴도 설치해줍니다. (저는 IDE 로 VSC 를 사용했습니다.)
이때 저는 공식 문서로 뭘 깔아야하는지 sdk 개념이 뭔지 zsh 사용 관련 어쩌고 저쩌고
어렵고 잘 모르겠더라구요!
그래서 플러터 배포 시 쓰는 도커 파일을 찾아봤습니다.
도커 파일을 확인한다면 설치할 때 필수적인게 뭔지 더 쉽게 파악할 수 있다고 판단했습니다.
# Environemnt to install flutter and build web
FROM debian:latest AS build-env
# install all needed stuff
RUN apt-get update
RUN apt-get install -y curl git unzip
# define variables
ARG FLUTTER_SDK=/usr/local/flutter
ARG FLUTTER_VERSION=3.10.5
ARG APP=/app/
#clone flutter
RUN git clone https://github.com/flutter/flutter.git $FLUTTER_SDK
# change dir to current flutter folder and make a checkout to the specific version
RUN cd $FLUTTER_SDK && git fetch && git checkout $FLUTTER_VERSION
# setup the flutter path as an enviromental variable
ENV PATH="$FLUTTER_SDK/bin:$FLUTTER_SDK/bin/cache/dart-sdk/bin:${PATH}"
# create folder to copy source code
RUN mkdir app
# copy source code to folder
COPY . /app
# stup new folder as the working directory
WORKDIR /app/
# Start to run Flutter commands
# doctor to see if all was installes ok
RUN flutter doctor -v
RUN flutter channel stable
RUN flutter config --enable-web
# RUN flutter upgrade
RUN flutter pub cache repair
RUN flutter pub upgrade
RUN flutter pub cache clean
# Run build: 1 - clean, 2 - pub get, 3 - build web
RUN flutter clean
RUN flutter pub get
RUN flutter build web --release
# once heare the app will be compiled and ready to deploy
# use nginx to deploy
FROM nginx:1.25.2-alpine
# copy the info of the builded web app to nginx
COPY --from=build-env /app/build/web /usr/share/nginx/html
# Expose and run nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
구글링해서 플러터 웹 배포 시 쓰는 도커 파일을 찾아보니 위 코드가 나왔습니다.
저 파일을 통해서 확인한 것은 2가지입니다. 공식문서와 대조하면서 확인했어요.
RUN flutter 어쩌고가 설치와 빌드 (정적 웹) 관련 핵심 명령어겠구나 이해했고
또 그리고 flutter 설치 시에 깃을 가져와서 뭔가 플러터 실행 관련 경로를 설정해주는구나! 그게 sdk 관련 경로 설정이 있는거구나!
그리고 nginx 설정은 필요없는거구요!
공식문서를 살펴보니 환경변수에 PATH 를 설정해주는데 영 찝찝했습니다. (zshrc 를 설치할 때 함부로 바꿨다가 고생한 적이 많았었어서요.)
그래서 다음 생각으로는 깃으로 설치가 된다면, homebrew 로도 충분히 지원하지 않을까? 라는 생각이 들어서 찾아봤습니다.
예전에 또 파이썬 경로 관련해서 homebrew 랑 경로 충돌이 일어난 경험이 있어서 웬만한 소프트웨어는 홈브루부터 찾아보게 되더라구요!
(파이썬 에러는 mise 라는 언어 패키지 관리자 툴을 활용해서 해결했습니다.)
'flutter homebrew start' 라고 찾아보니 관련 자료가 많습니다. 믿을만한 것 같아요.
flutter — Homebrew Formulae
깔아줍니다.
플러터가 깔렸습니다.
ㅡ 만약 flutter 경로 이슈가 있다면 이 작업 관련이 문제겠구나 메모도 해줍니다.
++ 3/19 수정: path 경로 이슈가 있어서 수정해줬습니다. path 는 상관이 없네요.
open -e ~/.zshrc
입력 후 path 기입해줍니다.
source ~/.zshrc
잘 설치되었는지 체줍니다.
flutter doctor -v
잘 됩니다.
저는 웹만 구현할거라서 안드로이드/IOS 관련은 보고도 모른척해줬습니다. ^^
(코틀린이랑 swift 도 궁금,,아이폰 쪽 object-c 어쩌고도 궁금....................................모르는게 너무 많아요!! 하지만 일단 우선순위에서 뺐어요 ㅠ.ㅠ)
이렇게 환경 세팅이 마무리 되었습니다.
읽어주셔서 감사합니다. 😄️
2024년 3월 19일 추가:
더 하다보니까 뭔가 상태관리 컴포넌트가 어렵다.. 싶어서 뭔가 더 있지 않을까 찾아봤는데요!!!
다음 블로그를 쓰려고 준비하다가 flutter 관련 VSC 익스텐션들을 살펴보다가 더 재밌는 것을 발견했습니다.
대박
자꾸 flutter 인기 많은 익스텐션에서 뭔가 Bloc 이라는 게 자꾸 나오길래 검색해봤더니 와우! MVVM 패턴을 사용한 상태관리 라이브러리라고 뭔가 엄청 좋은 자료들이 많이 나옵니다.
Bloc Concepts | Bloc (bloclibrary.dev)
위 링크에 가서 보니 개념적인 설명부터 구현까지 따라하기 좋게 잘 나와있습니다.
이 글에서도 플러터 자체 공식문서 불친절하고 불편하다고 불평 했었는데, 알고보니 이 bloc 라는 친구를 믿고 대충 기본 원리 개념만 알려준건가? 싶을 정도입니다.
Flutter 인기 아키텍처 라이브러리 3종 비교 분석 - GetX vs BLoC vs Provider (linecorp.com)
일단 플러터 기본적인 이해는 stateless 위젯이니 Future Stream 네비게이터 push 등등 일단 몰랐는데 이게 일단 구현하면서 참고한 레포지토리와 코드들이 있잖아요. 그때 자주 본 키워드 위주로 종종 찾아보면서 제가 예상한 기능과 어떻게 다른지 이렇게 이해하니까 중요한 개념이 모이는 기분입니다!
그래서 말인데 개념적인건 구글링해보면 공식문서와 다른 개발자분들이 잘 정리해둔 자료도 많고 오개념으로 이해한 것도 많을 것 같아 일단 패스할게요.
아무튼! 찾아보는데 플러터에게서 상태관리와 클래스 컴포넌트화에 대한 광기와 집념이 느껴집니다.
또 뭔가 구조를 잡아주는 익스텐션이 꽤 있어서 이것저것 시도해보려구요.
지금은 Provider 와 컴포넌트 상태관리, BloC 패턴과 MVVM 패턴 - 플러터 아키텍처 & 디렉터리 구조에 대해서 공부하고 있습니다.
BLoC 패턴이 rxjs 와 옵저버 패턴과 비슷하다는 점도 알게되어서 짜릿합니다. 와우~!!
Nest.Js 에서 Http Module 로 제공하는 외부 api 요청 라이브러리가 rxjs 로 되어있었거든요. 그때 옵저버 패턴과 async 가 비동기를 처리할때 어떻게 다른지 트레이드 오프가 뭔지 공부한 적이 있었는데 그때 봤던 개념이 여기서 이렇게 또 만나게 되었다는게 신기합니다.
플러터가 MVC 구조 등 여러가지 아키텍처로도 되는 것 같은데 이번에 한번 저는 MVVM 을 적용해보고, MVC 와 어떤 차이가 있는지도 감이 오지 않을까 기대됩니다.
아무튼. 추가 자료 정리 후 다음 블로그에서 이야기 해보도록 하겠습니다.
- 다음편에 계속 -