firebase에서 설명해주는 순서대로 진행하면 된다.
Flutter 앱에서 메시지 수신 | Firebase 클라우드 메시징
Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Flutter 앱에서 메시지 수신 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
firebase.google.com
1. firebase_messaging, flutter_local_notifications 패키지 추가
firebase_messaging | Flutter Package
Flutter plugin for Firebase Cloud Messaging, a cross-platform messaging solution that lets you reliably deliver messages on Android and iOS.
pub.dev
flutter_local_notifications | Flutter Package
A cross platform plugin for displaying and scheduling local notifications for Flutter applications with the ability to customise for each platform.
pub.dev
2. AndroidManifest.xml 에 추가
<manifest ...
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<application ...
3. IOS 권한 받기
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> requestPermission() async {
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}');
}
settings.authorizationStatus 값으로 권한 상태 확인 가능하다.
- authorized: 권한 부여
- denied: 권한을 거부
- notDetermined: 아직 권한 선택하지 않함
- provisional: 임시 권한
4. fcm토큰값 발행 코드 추가
해당 토큰을 저장해서 사용해야 한다. 백엔드에서 저장하는 로직이 필요하다.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final fcmToken = await FirebaseMessaging.instance.getToken();
log("fcmToken: $fcmToken");
runApp(const MyApp());
}
5. 백그라운드 상태에서 메세지 수신 코드 추가
@pragma('vm:entry-point') // Flutter 3.3 이상인 경우 @pragma 달기
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); // 추가
final fcmToken = await FirebaseMessaging.instance.getToken();
log("fcmToken: $fcmToken");
runApp(const MyApp());
}
6. 포그라운드 상태에서 메세지 수신 코드 추가
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}');
}
});
7. 메세지 수신 핸들링
이러한 이유로 안드로이드는 채널을 만들고 알림을 위해 flutter_local_notifications 패키지의 flutterLocalNotificationsPlugin을 사용해야 한다.
var channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // name
description: 'This channel is used for important notifications.', // description
importance: Importance.high,
);
var flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
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}');
flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification?.title,
message.notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '@mipmap/ic_launcher',
),
iOS: const DarwinNotificationDetails(
badgeNumber: 1,
subtitle: 'subtitle',
sound: 'slow_spring_board.aiff',
)
)
);
}
});
8. fcm 푸시 내용 작성
9. 기기로 발급받은 fcm 토큰 등록
10. 푸시 확인
클라우드 메세징 캠페인을 만들어서 푸시를 보내면 시간차가 조금 있는 듯하다.
개발할 때는 캠페인 만들기에서 테스트를 사용하는게 빠를 것 같다.
// main.dart
import 'dart:developer';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_notification/firebase_options.dart';
import 'package:flutter_notification/firebase_setting.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
final fcmToken = await FirebaseMessaging.instance.getToken();
log("fcmToken: $fcmToken");
setNotification();
runApp(const MyApp());
}
// firebase_setting.dart
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
// await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
Future<void> setNotification() async {
// 채널 생성
var channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // name
description: 'This channel is used for important notifications.', // description
importance: Importance.high,
);
var flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// 포그라운드 메세지 수신
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}');
flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification?.title,
message.notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '@mipmap/ic_launcher',
),
iOS: const DarwinNotificationDetails(
badgeNumber: 1,
subtitle: 'subtitle',
sound: 'slow_spring_board.aiff',
)
)
);
}
});
}
'dev > flutter' 카테고리의 다른 글
flutter - 앱 빌드 사이즈 확인 (0) | 2023.07.14 |
---|---|
flutter - 백그라운드 푸시 메세지 클릭 이벤트 (0) | 2023.07.10 |
안드로이드 에뮬레이터 에러 - [INSTALL_FAILED_INSUFFICIENT_STORAGE] (0) | 2023.06.29 |
안드로이드 스튜디오 AVD 추가하기 (0) | 2023.06.29 |
flutter - firebase 안드로이드 설정 (0) | 2023.06.24 |