Search
Duplicate
📲

iOS 푸시 알림 구현하기 세팅편 - AWS SQS, Lambda, Firebase

글감
노트
BE
FE
AWS
작성자
작성 일자
2023/07/19 07:07
상태
완료
공개여부
공개
Date
생성자
작업자

개요

이 글은 프론트엔드가 다루는 부분은 없고, 오로지 백엔드의 입장만 작성되어 있습니다.
iOS를 이용한 앱의 Java 백엔드를 담당하게 되면서, 앱 내 알림 및 Push 알림 기능 구현을 맡게 되었다. 이를 위해 DB 알림 관리와 Push 알림 전송 관리 구현이 필요했다. 방법들을 찾아보는 도중, AWS의 SQS, Lambda, 그리고 Google의 Firebase를 이용하면 무료로 이 알림들을 구현할 수 있음을 알게 되었다.
iOS 앱의 백엔드 서버로써 DB 알림과 Push 알림을 구현하기 위한 나의 삽질기를 기록하려고 한다.

AWS SQS, Lambda?

SQS(Simple Queue Service)마이크로서비스, 분산 시스템 및 서버리스 애플리케이션을 위한 완전관리형(알아서 해줌) 메시지 대기열이다.
Lambda는 서버를 프로비저닝 또는 관리하지 않고도 실제로 모든 유형의 애플리케이션 또는 백엔드 서비스에 대한 코드를 실행할 수 있는 이벤트 중심의 서버리스 컴퓨팅 서비스다.
TMI - Serverless?
간략한 구조도는 이렇다.
SQS에 원하는 메시지를 전송하면, Lambda에 이 메시지를 Event로 트리거(동작)하고, Lambda는 해당 Event에 대한 처리를 수행한다.

Firebase?

Firebase 는 BaaS(Backend-as-a-Service) 플랫폼으로 제공되는 포괄적인 도구 및 서비스 솔루션으로, 개발자가 모바일 및 웹 애플리케이션을 모두 쉽게 생성, 실행 및 확장할 수 있도록 해준다. 실시간 데이터베이스, 인증, 스토리지, 호스팅 및 기타 기능을 제공하며 모두 단일 플랫폼에서 관리가능하다.
한줄 요약: 백엔드에서 사용되는 여러 기능들을 통합적으로 제공하는 하나의 서비스

FCM?

FCM(Firebase Cloud Messaging)은 이름 그대로 클라우드 기반 메시지를 전송할 수 있는 Firebase의 플랫폼 솔루션이다. 기본적으로 무료이기 때문에, 그리고 여러 가지 기술들에도 적용할 수 있으며 우리의 경우 iOS 앱에서 이용할 수 있어서 선택했다.

굳이 SQS, Lambda를 사용하려는 이유

사실 FCM에 대해서 직접적으로 WAS(Spring Boot)에서 Push 알림을 전송할 수 있지만, 사용자의 증가로 인한 알림 처리의 증가와 이에 따른 서버의 리소스 사용을 고려하고자 했다.
확장적으로 생각했을 때 메시지 큐를 이용하여 별도의 처리 서버로 찢어놓는 것이 부하 분산뿐만아니라 스케일링에 있어서도 좋을 것이라고 생각했다. 따라서, ‘우리 서비스가 커지지 않을까?’라는 희망을 갖고, SQS와 Lambda를 이용해서 구현해보려고 한다.

SQS, Lambda 세팅하기

인스턴스 생성, 설정에 관련해서는 다른 좋은 글들이 많으니 구체적으로 적지는 않겠다. 우선, SQS와 Lambda를 연결해서 Event를 처리하는 작은 서버를 구현해보자.
Lambda 인스턴스 생성하기
SQS 인스턴스 생성하기
Lambda에 SQS에 대한 역할 부여해주기
SQS로 Lambda 트리거 등록하기
위의 과정들을 거쳤다면, 여기까지 왔을 것이다. 여기에서 SQS에 메시지를 보내면 해당 데이터가 이벤트로 트리거되어 람다가 처리한다.
이제 FCM을 설정해보러 가자.

FCM 앱 구성하기

FCM(웹페이지)에서 본인이 원하는 방식의 구성(Android, iOS, Web)을 선택하고, 앱 이름을 설정하면 프로젝트가 생성된다.
위 과정을 통해 첫 앱을 생성하였다면, ‘첫 번째 캠페인 만들기’가 활성화된다.
여기서 ‘테스트 메시지 전송’은 iOS의 경우 Device Token이 필요하다. Device Token은 FCM 모듈이 설치되어 있는 앱을 사용하면 사용하는 기기에 대해 식별자처럼 부여해주는 토큰을 의미한다.
iOS 앱에 대해 Device Token만 있다면, 바로 push 알림을 전송할 수 있다. 토큰을 받아오는 것은 해당 앱의 프론트엔드의 설정과 조회로 가능하므로, 이 부분에서는 생략한다.
위 FCM에 대한 구성을 마쳤다면, 위 그림처럼 준비가 끝난 것이다. 이제, DeviceToken을 가지고 SQS-Lambda를 연결해보자.

Lambda에서 FCM으로 메시지 전송하기

주의사항
Lambda를 설정할 때, Node.js의 경우에는 메시징을 위해 사용해야하는 모듈인 firebase-admin의 의존성 용량이 람다가 기본적으로 수용할 수 있는 용량을 넘어가게 되므로, Python을 사용하는 것이 정신건강에 좋다..!
FCM을 사용하기 위해, 다음 의존성을 설치해야한다.
pip3 install firebase-admin
YAML
복사
람다 자체에 해당 모듈을 넣고 람다 함수를 작성해도 되지만, Lambda에는 Layer라는 것을 통해 모듈을 Import할 수 있게끔 설정해줄 수 있다.

Lambda Layer에 의존 모듈 추가하기

Lambda의 Layer 혹은 계층에서 추가를하려고 하면, 다음과 같은 창이 나타난다.
Python의 firebase-admin 모듈은 압축하면 꽤나 가벼우므로, ‘.zip 파일 업로드’로도 가능하다. → 주의사항 - firebase-admin 모듈을 위에서 설치했다면, 해당 모듈의 최상위 폴더를 ‘python’이라는 이름으로 변경, 압축하여 업로드해야지 람다가 알아듣는다!
‘호환 아키텍처’는 Lambda의 런타임 환경과 동일하게 한다. - Python의 경우 x86_64에 해당한다.
‘호환 런타임’은 Lambda의 런타임 환경과 동일하게 한다. - 나의 경우 Python 3.7로 설정했다.
이후에 계층을 추가하면 모듈 설정 완료!

FCM에 메시지를 전송하는 Lambda 함수 작성하기

lambda 함수에 들어오는 event를 따로 설정할 수도 있고, 이에 대해서 Test도 가능하다.
FCM에 원하는 Push 알림을 전송하기 위해, 다음과 같은 것들이 필요하다.
firebase-admin 모듈(방금 설치함)
FCM 앱 config(secret)
받아오는 방법
메시지를 전송할 기기의 Device Token(프론트에서 줬다고 가정)
이후에, 다음과 같이 작성하면 푸시 알림을 보낼 수 있다!
import firebase_admin as admin from firebase_admin import credentials from firebase_admin import messaging # 어드민 계정 정보를 이용해 firebase-admin을 초기화 cred = credentials.Certificate('diary_admin_config.json') admin.initialize_app(cred) # 람다 핸들러 def lambda_handler(event, context): parsed_payload = parse_sqs_message(event) return send_notification(parsed_payload); # firebase 모듈을 이용한 푸시 알림 message send def send_notification(payload): message = messaging.Message( notification=messaging.Notification( title=payload['title'], body=payload['payload'] ), token=payload['deviceToken'] ) print(message) return messaging.send(message) # sqs 메시지 파싱 def parse_sqs_message(sqs_message): title = sqs_message['Records'][0]['messageAttributes']['title']['stringValue'] deviceToken = sqs_message['Records'][0]['messageAttributes']['deviceToken']['stringValue'] payload = sqs_message['Records'][0]['body'] return {"title": title, "payload": payload, "deviceToken": deviceToken}
Python
복사
SQS 메시지(JSON)에 대해 딕셔너리로 변경하는 간단한 파싱을 구현 - 단순 전달하게끔 해놓았다.
‘title’이나 ‘deviceToken’ 같은 경우에는 이 정보를 담은 메시지를 전송하는 백엔드 서버에서 임의로 집어넣은 부분이어서 추가적인 구현이 필요하다(다음 구현편에 내용 있음).

정리

여기까지 구성했다면 우리는 위 구조를 구성한 것이다.
SQS - Lambda - FCM을 이용해서 푸시 알림을 위한 세팅을 해보았다.
꽤 많은 삽질이 생략되었지만, 필요한 부분은 이 정도면 충분한 것 같다. 물론 서비스가 거대해진다면 메시징 기법과 정합성에 대해서 고민을 더 해봐야 할 것 같다.
이제, SQS에 이 메시지를 어떻게 잘 보낼지에 대해 Spring Boot 기반 상세구현을 해보자!
→ (작성 예정)

참고자료