
모바일 앱에서 사용자 참여도를 높이는 가장 효과적인 방법 중 하나가 바로 푸시 알림입니다. Firebase Cloud Messaging(FCM)을 사용하면 Flutter 앱에서 Android, iOS, 웹 플랫폼 모두에 일관된 푸시 알림을 구현할 수 있습니다. 이번 포스팅에서는 2025년 최신 정보를 바탕으로 FCM 푸시 알림을 단계별로 구현하는 방법을 자세히 알아보겠습니다.
Firebase 프로젝트 설정
Firebase 프로젝트 생성
먼저 Firebase 콘솔에 접속하여 새 프로젝트를 생성합니다.
- Firebase 콘솔 접속
- 프로젝트 추가 클릭
- 프로젝트 이름 입력 (예: "push-notifications")
- Google 애널리틱스 설정 (선택사항)
- 프로젝트 만들기 클릭
앱 등록 및 구성 파일 다운로드
Android 설정:
- Android 아이콘 클릭
- 패키지 이름 입력 (
android/app/src/main/AndroidManifest.xml에서 확인 가능) google-services.json파일 다운로드- 파일을
android/app/디렉토리에 배치
iOS 설정:
- iOS 아이콘 클릭
- 번들 ID 입력
GoogleService-Info.plist파일 다운로드- Xcode에서 Runner 프로젝트에 파일 추가
Flutter 프로젝트 설정
의존성 추가
pubspec.yaml 파일에 필요한 패키지들을 추가합니다:
dependencies:
firebase_core: ^3.14.0
firebase_messaging: ^15.2.7
flutter_local_notifications: ^19.1.0
터미널에서 의존성을 설치합니다:
flutter pub get
Firebase 초기화
main.dart 파일을 수정하여 Firebase를 초기화합니다:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
// 백그라운드 메시지 핸들러
@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print('백그라운드 메시지 처리: ${message.messageId}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// 백그라운드 메시지 핸들러 등록
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
푸시 알림 핸들링 구현
권한 요청 및 FCM 토큰 획득
사용자에게 알림 권한을 요청하고 FCM 토큰을 획득합니다:
class NotificationService {
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
// 알림 권한 요청
static Future requestPermission() async {
NotificationSettings settings = await _firebaseMessaging.requestPermission(
alert: true,
badge: true,
sound: true,
provisional: false,
);
print('권한 상태: ${settings.authorizationStatus}');
}
// FCM 토큰 획득
static Future getToken() async {
String? token = await _firebaseMessaging.getToken();
print('FCM Token: $token');
return token;
}
}
알림 리스너 설정
포그라운드, 백그라운드, 종료 상태에서의 알림을 처리합니다:
class NotificationHandler {
static void setupInteractedMessage() {
// 포그라운드 메시지 처리
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('포그라운드 메시지 수신: ${message.notification?.title}');
_showLocalNotification(message);
});
// 백그라운드에서 알림 탭으로 앱 열기
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('알림으로 앱 열기: ${message.notification?.title}');
_handleNotificationTap(message);
});
}
static void _showLocalNotification(RemoteMessage message) {
// 로컬 알림 표시 로직
}
static void _handleNotificationTap(RemoteMessage message) {
// 알림 탭 처리 로직
}
}
로컬 알림 표시
포그라운드 상태에서 알림을 표시하기 위해 로컬 알림을 구현합니다:
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class LocalNotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static Future initialize() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestSoundPermission: true,
requestBadgePermission: true,
requestAlertPermission: true,
);
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _notificationsPlugin.initialize(initializationSettings);
}
static Future showNotification(RemoteMessage message) async {
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'high_importance_channel',
'High Importance Notifications',
channelDescription: '이 채널은 중요한 알림에 사용됩니다.',
importance: Importance.max,
priority: Priority.high,
showWhen: false,
);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await _notificationsPlugin.show(
0,
message.notification?.title,
message.notification?.body,
platformChannelSpecifics,
);
}
}
플랫폼별 추가 설정
Android 설정
android/app/build.gradle 파일에 Google Services 플러그인을 추가합니다:
apply plugin: 'com.google.gms.google-services'
android/build.gradle 파일의 dependencies에 추가:
dependencies {
classpath 'com.google.gms:google-services:4.4.0'
}
iOS 설정
ios/Runner/AppDelegate.swift 파일을 수정합니다:
import UIKit
import Flutter
import Firebase
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Xcode에서 Signing & Capabilities → Push Notifications 기능을 추가해야 합니다.
완전한 구현 예제
다음은 모든 기능을 통합한 완전한 예제입니다:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
class PushNotificationApp extends StatefulWidget {
@override
_PushNotificationAppState createState() => _PushNotificationAppState();
}
class _PushNotificationAppState extends State {
String? _token;
@override
void initState() {
super.initState();
_initializeNotifications();
}
Future _initializeNotifications() async {
// 권한 요청
await FirebaseMessaging.instance.requestPermission();
// 토큰 획득
String? token = await FirebaseMessaging.instance.getToken();
setState(() {
_token = token;
});
// 메시지 리스너 설정
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('알림 수신: ${message.notification?.title}')),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('푸시 알림 데모'),
backgroundColor: Colors.blue,
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'FCM 토큰:',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Text(
_token ?? '토큰을 가져오는 중...',
style: TextStyle(fontSize: 12),
),
],
),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
String? newToken = await FirebaseMessaging.instance.getToken();
setState(() {
_token = newToken;
});
},
child: Text('토큰 새로고침'),
),
],
),
),
);
}
}
테스트 방법
Firebase 콘솔에서 테스트
- Firebase 콘솔 → Cloud Messaging 메뉴
- 새 알림 작성 클릭
- 제목과 내용 입력
- 대상 선택 (특정 토큰 또는 주제)
- 게시 클릭
cURL을 사용한 테스트
curl -X POST --header "Authorization: key=" \
--header "Content-Type: application/json" \
https://fcm.googleapis.com/fcm/send \
-d '{
"to":"",
"notification":{
"title":"테스트 알림",
"body":"FCM 테스트가 성공했습니다!"
}
}'
주요 이슈 해결
일반적인 문제들
iOS에서 알림이 오지 않는 경우:
- Xcode에서 Push Notifications capability 추가 확인
- 개발자 계정의 APNs 인증서 설정 확인
백그라운드에서 알림을 받지 못하는 경우:
- Background App Refresh 설정 확인
onBackgroundMessage핸들러 등록 확인
토큰이 생성되지 않는 경우:
Firebase.initializeApp()호출 확인- 네트워크 연결 상태 확인
- 구성 파일 위치 확인
마무리
Flutter에서 Firebase Cloud Messaging을 활용한 푸시 알림 구현은 몇 가지 핵심 단계를 정확히 따르면 비교적 간단하게 구현할 수 있습니다. Firebase 프로젝트 설정부터 플랫폼별 구성, 권한 요청, 메시지 핸들링까지 각 단계를 꼼꼼히 진행하는 것이 중요합니다.
이렇게 구현된 푸시 알림 시스템을 통해 실시간 업데이트, 마케팅 메시지, 개인화된 알림 등 다양한 사용자 참여 기능을 앱에 추가할 수 있습니다. FCM의 강력한 기능들을 활용하여 사용자 경험을 한층 더 향상시켜보세요.
앞으로도 Flutter와 Firebase의 다양한 기능들을 적극 활용하여 더욱 스마트하고 사용자 친화적인 모바일 앱을 개발해나가시기 바랍니다.
[Flutter] 플러터와 피그마 연동하여 디자인을 코드로 변환하는 실전 가이드
플러터(Flutter)와 피그마(Figma)의 연동은 디자이너와 개발자 모두에게 생산성 혁신을 가져다주는 핵심 트렌드입니다. 이 글에서는 피그마에서 디자인한 UI를 플러터 코드로 자동 변환하는 대표적
hoosfa.tistory.com
'IT기술 > 플러터 (flutter)' 카테고리의 다른 글
| Flutter 앱 아키텍처 완벽 가이드: MVC, MVVM, Clean Architecture 비교 분석 (0) | 2025.07.05 |
|---|---|
| Flutter에서 WebSocket을 활용한 실시간 앱 개발 완벽 가이드 (4) | 2025.07.04 |
| [Flutter] 플러터와 피그마 연동하여 디자인을 코드로 변환하는 실전 가이드 (2) | 2025.04.29 |
| [Flutter] Android Studio에서 사용 가능한 플러터 단축키 모음 (2) | 2025.04.19 |
| 플러터 앱을 만들기 위한 필수 지식: 기초부터 실전까지 (2) | 2025.04.09 |