이 포스팅은 Flutter 3.24 버전 기준으로 작성되었습니다.
FCM 아키텍처 개요 - (출처) https://firebase.google.com/docs/cloud-messaging/fcm-architecture
Firebase Cloud Messaging(FCM)은 무료로 메시지를 안정적으로 전송할 수 있는 크로스 플랫폼 메시징 솔루션입니다.
FCM 구현에는 송수신을 위한 두 가지 주요 구성요소가 필요하며 간단히 설명하면 다음과 같습니다.
Cloud Functions for Firebase 또는 앱 서버와 같이 메시지를 작성, 타겟팅, 전송할 수 있는 신뢰할 수 있는 환경
해당 플랫폼별 전송 서비스를 통해 메시지를 수신하는 Apple, Android 또는 웹(자바스크립트) 클라이언트 앱
주로 1번은 백엔드 서버, 2번은 플러터 앱이라고 보시면 됩니다. 이번 포스팅에서는 주로 2번, 플러터 앱에서 FCM토큰을 발급받고, 푸쉬 알림을 수신하는 방법을 알아보겠습니다.
Apple developer 계정이 필요합니다. 없다면
Apple Developer↗ 에 가입, 폭은 이 과정은 패스 후 안드로이드만 진행해주세요
임의의 이름을 입력 후 APNs를 선택합니다.
Configure 버튼을 눌러 목적에 맞게 원하는 속성을 선택해 설정을 마무리합니다.
설정 완료 후 Continue -> Register 버튼을 차례로 눌러 키 생성을 완료해주세요.
🖐️
주의!!!! 여기서 꼭 키를 다운받아 잘 저장해주세요.
완료되었다면 다음과 같이 key가 발급되게 됩니다.
App IDs를 선택, 다음 창에서 App을 선택하고 Continue 합니다.
설명, 번들ID 입력 후 아래로 쭉 내려 Push Notifications 체크 후 Continue, Register 버튼을 차례로 눌러 식별자 생성을 완료해주세요.
Bundle ID는 /ios/Runner.xcodeproj/project.pbxproj
파일에 있는 PRODUCT_BUNDLE_IDENTIFIER
값입니다(예시: com.example.promleeblog
).
✅
1.3. Xcode Capability 추가 🔗
VSCode에서
/ios
폴더에 우클릭 후 Open in Xcode 버튼을 눌러 Xcode로 열어줍니다.
Runner > Runner > Signing & Capabilities
탭으로 이동 후
+ Capability
버튼 클릭 후
Push Notifications
를 검색해 추가해줍니다.
추가적으로 Signing & Capabilities
탭에서 Background Modes에 다음과 같이 체크해줍니다.
✅
1.4. Firebase Cloud Console 설정 🔗
팀 ID 위치
이렇게 IOS환경에서 설정을 마무리 했습니다.
/ios/Podfile
파일에 다음과 같이 권한을 추가해줍니다. 이미 추가되어있는 경우는 PERMISSION_NOTIFICATIONS
항목이 주석 해제되어있는지만 확인해주시면 됩니다.
Podfile 코드 /ios/Podfile post_install do |installer|
installer. pods_project . targets . each do |target|
flutter_additional_ios_build_settings (target)
target. build_configurations . each do |config|
# You can remove unused permissions here
# for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
config. build_settings [ 'GCC_PREPROCESSOR_DEFINITIONS' ] ||= [
'$(inherited)' ,
## dart: PermissionGroup.calendar
# 'PERMISSION_EVENTS=1',
## dart: PermissionGroup.calendarFullAccess
# 'PERMISSION_EVENTS_FULL_ACCESS=1',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=1',
## dart: PermissionGroup.contacts
# 'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
# 'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
# 'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
# 'PERMISSION_SPEECH_RECOGNIZER=1',
## dart: PermissionGroup.photos
# 'PERMISSION_PHOTOS=1',
## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
## macro.
##
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
# 'PERMISSION_LOCATION=1',
# 'PERMISSION_LOCATION_WHENINUSE=0',
## dart: PermissionGroup.notification
'PERMISSION_NOTIFICATIONS=1' ,
## dart: PermissionGroup.mediaLibrary
# 'PERMISSION_MEDIA_LIBRARY=1',
## dart: PermissionGroup.sensors
# 'PERMISSION_SENSORS=1',
## dart: PermissionGroup.bluetooth
# 'PERMISSION_BLUETOOTH=1',
## dart: PermissionGroup.appTrackingTransparency
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_CRITICAL_ALERTS=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_ASSISTANT=1',
]
end
end
end
안드로이드는 권한 설정만 해주시면 됩니다.(Android 13(API 수준 33) 이상)
/android/app/src/main/AndroidManifest.xml < manifest ...>
< uses-permission android:name = "android.permission.POST_NOTIFICATIONS" />
< application ...>
...
</ application >
</ manifest >
🚀
3. 푸쉬 알림 수신 Flutter 코드 작성하기 🔗
✅
3.1. firebase_messaging 패키지 설치하기 🔗
flutter pub add firebase_messaging
알림 수신 권한 허용을 받을 위치에 다음 코드를 추가합니다.
import 'package:firebase_messaging/firebase_messaging.dart' ;
// 적절한 위치에 선언
FirebaseMessaging messaging = FirebaseMessaging .instance;
NotificationSettings settings = await messaging. requestPermission (
alert : true ,
announcement : false ,
badge : true ,
carPlay : false ,
criticalAlert : false ,
provisional : false ,
sound : true ,
);
print ( 'User granted permission: ${ settings . authorizationStatus } ' );
✅
3.3. 푸쉬 알림 수신 코드 작성 (백그라운드) 🔗
가장 상위 파일인 main.dart에 다음 코드를 추가합니다.
백그라운드 메시지 핸들러와 관련하여 유의해야 할 몇 가지 사항이 있습니다. 주의해주세요
익명 함수가 아니어야 합니다.
최상위 수준 함수여야 합니다(예: 초기화가 필요한 클래스 메서드가 아님).
Flutter 버전 3.3.0 이상을 사용하는 경우 메시지 핸들러는 함수 선언 바로 위에 @pragma('vm:entry-point')로 주석을 달아야 합니다(그렇지 않으면 출시 모드의 경우 트리 쉐이킹 중에 삭제될 수 있음).
/lib/main.dart import 'package:firebase_messaging/firebase_messaging.dart' ;
@pragma ( 'vm:entry-point' )
Future < void > _firebaseMessagingBackgroundHandler ( RemoteMessage message) async {
await Firebase . initializeApp ();
}
void main () {
FirebaseMessaging . onBackgroundMessage (_firebaseMessagingBackgroundHandler);
runApp ( MyApp ());
}
✅
3.4. 푸쉬 알림 수신 코드 작성 (포그라운드) 🔗
가장 상위 파일에 다음과 같은 리스너를 추가합니다.
/lib/main.dart import 'package:firebase_messaging/firebase_messaging.dart' ;
void main (){
// ...
FirebaseMessaging .onMessage. listen (( RemoteMessage message) {
print ( 'Got a message whilst in the foreground!' );
print ( 'Message data: ${ message . data } ' );
if (message.notification != null ) {
print ( 'Message also contained a notification: ${ message . notification } ' );
}
});
runApp ( MyApp ());
}
FCM 토큰은 플러터 앱에서 FCM 서버와 통신하기 위해 사용되는 고유 식별자입니다. 플러터 앱에서 FCM 토큰을 발급받으면 푸쉬 알림을 수신할 수 있습니다.
import 'package:firebase_messaging/firebase_messaging.dart' ;
// 적절한 위치에 선언
final req = await FirebaseMessaging .instance. requestPermission (
alert : true ,
badge : true ,
sound : true ,
);
final fcmToken = await FirebaseMessaging .instance. getToken ();
if (req.authorizationStatus == AuthorizationStatus .authorized && fcmToken != null ) {
print ( 'FCM Token: $ fcmToken ' );
} else {
print ( 'FCM Token: null' );
}
알림 작성 버튼이 나타나면 알림 제목, 텍스트 입력 후 테스트 메시지 전송 버튼을 눌러 위에서 발급한 FCM 토큰에 푸쉬 알림을 보낼 수 있습니다.
apns token has not been set yet. please ensure the apns token is available by calling getapnstoken()
기본적인 설정을 모두 제대로 했는데도 해당 에러가 발생한다면 flutter에서 APNS 토큰을 자동으로 발급받지 못하는 버그가 발생한 것입니다. 그렇기에 수동으로 APNS 토큰을 발급받아야 합니다.
/lib/main.dart import 'package:firebase_messaging/firebase_messaging.dart' ;
import 'package:flutter/material.dart' ;
void main () async {
WidgetsFlutterBinding . ensureInitialized ();
FirebaseMessaging messaging = FirebaseMessaging .instance;
await messaging. requestPermission (
alert : true ,
announcement : false ,
badge : true ,
carPlay : false ,
criticalAlert : false ,
provisional : false ,
sound : true ,
);
messaging. getAPNSToken (); // 이 코드 추가
await messaging. getToken ();
runApp ( MyApp ());
}
IOS 실 기기에 앱을 설치하고 실행하면 위와 같은 에러가 발생할 수 있습니다. 이는 IOS에서 FCM 토큰을 발급받기 위해 APNs 토큰이 필요하기 때문입니다. 이 문제를 해결하기 위해서는 앱을 실행하고 APNs 토큰을 발급받은 후 FCM 토큰을 발급받아야 합니다. 이를 해결하기 위해 다음과 같이 코드를 수정해줍니다.
파이어베이스의 클라우드 메시징을 사용하면 푸쉬 알림을 쉽게 보낼 수 있습니다. 하지만 푸쉬 알림 클릭 시 특정 페이지로 이동하거나 특정 행동을 실행하는 기능은 구현하기 어렵습니다. 이 기능을 구현하기 위해서는 추가적인 작업이 필요합니다. 이 부분은 다음 포스팅에서 다루도록 하겠습니다.
HTTP v1 API 사용해서 푸쉬 알림 보내기
푸쉬 알림 클릭 시 특정 페이지로 이동하기
푸쉬 알림 클릭 시 특정 행동 실행하기