GCP Cloud Function으로 FCM 메시지 보내기 + Pub/Sub

GCP Cloud Function으로 FCM 메시지 보내기 + Pub/Sub

GCP Cloud Function과 Pub/Sub을 연동해서 FCM (Firebase Cloud Messaging) 사용하는 방법을 기록으로 남깁니다

대용량 FCM 메시지 보내기 위해 PubSub을 GCP로 구현한 두번째 내용입니다

이전 글에서는 GCP Pub/Sub 만드는 내용을 다루었고 이번 내용은 GCP Cloud Function을 구현하는 내용입니다

모든 코드는 github에서 확인할 수 있습니다

github에 테스트 코드도 함께 작성해놓았습니다 본문에는 따로 기재를 하지 않았지만 함께 확인하시면 좋습니다

1. Pub/Sub과 연동된 Cloud Function 생성

함수 이름과 GCP Pub/Sub의 topic을 선택하고 NEXT를 선택합니다

2. Cloud Function 언어 선택

.NET, Go, Java, Node, Python, PHP, Ruby 가 가능합니다 저는 개인적으로 가볍고 이식성이 좋은 언어로 AWS Lambda나 GCP Cloud Function을 짜는 것을 좋아합니다 그래서 Python, Node를 선호하고 이번에는 Python으로 선택했습니다

3. 파이썬 프로젝트를 생성하고 firebase admin sdk를 설치합니다

# initialize project pyenv local 3.9.6 # python 3.9.6 버전으로 작업 python3 -m venv venv # virtual environment 생성 source venv/bin/activate # virtual environment 활성화

# install firebase admin package pip install firebase-admin

4. firebase service account를 다운로드 받습니다

GCP에서 인증하는 방식은 여러가지 입니다 저는 그 중에서 service account 키 파일을 이용해서 인증을 했습니다 Firebase Console > 프로젝트 설정 > 서비스 계정 > 새 비공개 키 생성

code snippet 입니다

# main.py # code snippet import firebase_admin from firebase_admin import credentials ... cred = credentials.Certificate("./pointberry-292606-firebase-adminsdk.json") firebase_admin.initialize_app(cred) ....

5. main.py 코드 작성

entrypoint 함수의 첫번째 파라미터 event의 data 필드에는 base64로 인코딩된 PubSub Message가 있습니다 event를 디코딩한 뒤에 메시지 내용을 추출합니다

# main.py import base64 import json import logging from enum import Enum from typing import Optional import firebase_admin from firebase_admin import credentials from firebase_admin import messaging # https://cloud.google.com/functions/docs/calling/pubsub def entrypoint(event: dict, context) -> str: FIREBASE_ACCOUNT_SERVICE = "./sample-project-5d15z-firebase-adminsdk-gabge-4fa79ee667.json" try: cred = credentials.Certificate(FIREBASE_ACCOUNT_SERVICE) firebase_admin.initialize_app(cred) except ValueError: # The default Firebase app already exists. This means you called initialize_app() more than once pass logging.info("event: ", event) print("event:", event) data = json.loads(base64.b64decode(event['data']).decode('utf-8')) push_type: str = data['pushType'] if push_type != PushType.SINGLE_MESSAGE.name: print("Not supported message type", push_type) device_token = data['deviceToken'] title: str = data['title'] body: str = data['body'] metadata: dict = data.get('data', None) return send_one_data(device_token, title, body, metadata) def send_one_data(device_token: str, title: str, body: str, data: Optional[dict]) -> str: message = messaging.Message( notification=messaging.Notification(title=title, body=body), data=data, token=device_token, ) try: response = messaging.send(message) print("successfully Sent message:", response) return f"successfully Sent message: {response}" except firebase_admin._messaging_utils.UnregisteredError: print(f"No such deviceToken: {device_token}") return f"No such deviceToken: {device_token}" except firebase_admin.exceptions.InvalidArgumentError: return f"The registration token is not a valid FCM registration token: ${device_token}" class PushType(Enum): SINGLE_MESSAGE = 1 MULTIPLE_MESSAGE = 2

6. requirements.txt 작성

pip freeze > requirements.txt

생성된 requirements.txt 파일입니다

# requirements.txt CacheControl==0.12.6 cachetools==4.2.2 certifi==2021.5.30 cffi==1.14.6 charset-normalizer==2.0.4 firebase-admin==5.0.1 google-api-core==1.31.1 google-api-python-client==2.15.0 google-auth==1.34.0 google-auth-httplib2==0.1.0 google-cloud-core==1.7.2 google-cloud-firestore==2.2.0 google-cloud-storage==1.41.1 google-crc32c==1.1.2 google-resumable-media==1.3.3 googleapis-common-protos==1.53.0 grpcio==1.39.0 httplib2==0.19.1 idna==3.2 msgpack==1.0.2 packaging==21.0 proto-plus==1.19.0 protobuf==3.17.3 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycparser==2.20 pyparsing==2.4.7 pytz==2021.1 requests==2.26.0 rsa==4.7.2 six==1.16.0 uritemplate==3.0.1 urllib3==1.26.6

7. Cloud Function을 설정합니다

Entry point는 entrypoint 로 함수로 설정합니다 main.py는 위에서 작성한 main.py 를 복붙합니다 requirements.txt도 requirements.txt 파일을 복붙합니다 sample-project-5d15z-firebase-adminsdk-gabge-4fa79ee667.json 을 생성합니다

8. Deploy 버튼을 눌러서 배포합니다

Refer

from http://mycloudy.tistory.com/46 by ccl(A) rewrite - 2021-09-29 18:26:24