Firebase Cloud Messaging

박형석·2021년 11월 21일
0

개발

목록 보기
3/4
post-thumbnail

Firebase Cloud Messaging

FCM은 무료로 메시지를 보낼 수 있는 크로스 플랫폼 메시징 솔루션이다. 이 알림 메시지로 사용자를 유지하고 재참여를 유도할 수 있다. FCM에도 다양한 기능이 있는데, 기본 메시지를 보내는 기능 구현 및 동작에 대해서 이야기 해보자.

APNs란?

애플의 메시지(알림) 발송 서비스다. 이 서비스를 사용하기 위해서는 인증서가 필요하고 필요에 따라 P8, P12, PEM 파일이 사용된다. 여기서 FCM는 Provider의 역할을 하기 때문에 결국 APNs의 인증서, 그리고 앱을 APNs에 등록하는 절차가 필요하다.

APNs 인증서 받기 및 등록하기

1. 개발자 계정에서 APNs 인증받기

iOS 사용자에게 푸쉬 알림을 보내려면 APNs Push Certificate나 APNs Auth Key를 업로드 해야 한다. Certificate도 좋지만 Key를 사용하면 매년 Certificate를 다시 설정할 필요가 없고 하나의 인증키로 모든 앱에 사용할 수 있기 때문에 인증서를 유지하고 관리하는데 유용하다.

APNs Auth Key를 사용해서 푸쉬 알림을 보낼 때 앱에 대한 다음 정보가 필요하다.

  • Auth key file (p8)
  • Team ID
  • App의 bundle ID

아래 개발자 계정에서 활성화가 가능하다.

https://developer.apple.com/account/#!/welcome

코드사이닝에 대해서
https://beankhan.tistory.com/115

2. 앱에 APNs 등록하기 : Capability

다음으로는 xcode의 Target에서 Capability, Push Notification을 활성화해야 한다. iOS에서 이 기능을 활성화하면 APS Environment Entitlement(Push Notification을 위한 환경)을 추가한다.

3. 앱에 APNs 등록하기 : AppDelegate

이제 우리 앱을 APNs에 등록하는 코드를 작성해보자. 참고로 APNs의 등록하는 작업은 앱이 실행될 때마다 진행된다. 그래서 AppDelegate에서 코드를 작성한다.

// application(:didFinishLaunchingWithOptions:)
application.registerForRemoteNotifications()

언급했던 것처럼 앱이 런칭될 때마다 등록할 예정이기에 AppDelegate의 application(:didFinishLaunchingWithOptions)에 구현한다. iOS와 tvOS에서는 UIApplication의 registerForRemoteNotifications() 메서드를 호출해서 APNs 등록하고 device token을 요청할 수 있다. 성공적으로 APNs에 연결이 되면 다음 두 메소드로 성공 및 에러 처리를 할 수 있다.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { }
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { }

우리 앱을 APNs에 등록하면 앱은 APNs(Apple Push Notification service)와 통신해서 앱의 식별하는 unique device token을 받게 된다. 이 device token이 알림을 보내는데 어떤 역할을 할까? 간단히 말하자면, APNs가 각 디바이스에 알림을 보내기 위해는 사전에 사용자 디바이스의 주소를 알아야 한다. 그리고 이 주소는 기기와 앱 모두에게 고유한 것이어야 하고 이 주소가 없이 알림은 목적지를 찾을 수 없다. 바로 이 주소의 역할을 하는 것이 device token이다. APNs를 등록하고 난 뒤 앱을 실행하면 우리 앱은 APNs와 통신해서 device token을 받는다. 그리고 provider server(푸쉬 알림을 관리하는 서버)에 이 토큰을 전달한다. 그러면 서버는 해당 토큰을 포함하고 있기 때문에 지정된 사용자 장치의 앱으로 알림을 푸쉬 할 수 있는 것이다.

Registering Your App with APNs
https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns

UNUserNotificationCenter 설정하기

UNUserNotificationCenter는 알림 관련 활동을 관리하기 위한 중앙 객체다. 아래 문서에 자세히 나와있지만 주목할 부분은 "Process the payloads from remote notifications the system delivers by Apple Push Notification service (APNs)." 즉, APNs에서 전달되는 remote notification으로부터 payloads를 처리한다는 점이다. 물론 payloads가 아닌 일반 알림도 수신 처리한다.

UNUserNotificationCenter
https://developer.apple.com/documentation/usernotifications/unusernotificationcenter

아무튼 이 부분도 앱에서 설정해주어야 알림을 수신하거나 처리할 수 있다. 다음과 같은 코드로 구현한다.

import UserNotifications
// application(:didFinishLaunchingWithOptions:)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { _, _ in })
extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions)
                                -> Void) {
        completionHandler([[.alert, .badge, .sound]])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }
}

FCM 설정하기


위에서 언급했던 것처럼 iOS기기에 메시지를 보내기 위해 FCM은 APNs를 사용한다. 그래서 위에서 필요한 인증 및 등록 절차를 밟았고 device token도 받았다. 또 알림을 수신하기 위해서 UNUserNotificationCenter 설정도 해주었다.이제 APNs에서 받은 device token을 provider server로 전송해서 알림을 수신하는 일만 남았다. 우리는 이 작업을 FCM과 함께 할 예정이다.

1. 앱 정보 등록하기

가장 먼저 Firebase에서 우리 앱을 프로젝트로 등록한 뒤, 위에서 얻은 앱 정보, 즉 Auth Key file, Team ID, App's Bundle ID를 FCM에 등록해서 APNs에게 notification을 전달할 권한을 부여한다.

2. 클라이언트 코드 구현

다른 과정을 거의 다 짜맞춰졌는데, 아직 device token을 provider server에게 전달하지 않았다. 여기서 좀 반전이 있는데 우리는 이 APNs와 통신의 결과로 얻은 device token을 직접 전달하지 않을 거라는 점이다. 위의 그림에서 보는 것처럼 우리는 FCM과의 통신을 통해 얻은 device token을 사용할 예정이다. 이걸 백앤드 서버&DB에 저장한 뒤 알림을 초기화해서 FCM으로 전달, APNs로 전송한다.

여기서 '직접' 전달하지 않는다는 말은 모호한 말이다. APNs에서 받은 token을 아에 사용하지 않는지, 아니면 FCM token을 받아오는 과정에서 APNs의 token을 사용하는지 이 사이를 어떻게 연결하는지 찾지 못했다..

아무튼 말은 길지만 이 과정의 코드는 아주 짧다. 일은 프레임워크가 다해주기 때문에 따로 추가할 코드는 없다. 아래 messaging(:didReceiveRegistrationToken:) 메소드로는 갱신되는 모든 토큰을 모니터링 할 수 있다.

import FirebaseMessaging

// application(:didFinishLaunchingWithOptions:)
Messaging.messaging().delegate = self

extension AppDelegate : MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("파이어베이스 토큰: \(String(describing: fcmToken))")
    }
}

우리가 보낸 메시지에 대한 수신 정보를 analytics에 전달하려면 appDidReceiveMessage(_:) 메서드를 사용하면 된다. 위 UserNotifications의 알림 수신 및 알림 처리 메서드에 다음 메서드를 추가하면 된다.

Messaging.messaging().appDidReceiveMessage(userInfo)

정리

단순하게 FCM를 기본만 딱 사용하는거라면 정말 간단하게 구현할 수 있다. 하지만 APNs와의 관계, 인증, 전체 워크플로우를 고민하면서 작성하다보니 생각보다 오래 걸렸다. FCM은 사실 단순히 메시지를 보내는 것 외에도 정말 다양한 기능이 있다. 페이로드, 여러 기기에 메시지 보내기, 주제별, 기기별 메시지 전송 등 다양한 기술이 있으니 필요할 때마다 찾아서 사용해보면 좋을 것 같다.

profile
IOS Developer

0개의 댓글

관련 채용 정보