저번 글에 이어 클라이언트 단에서의 푸시 알림 구현을 진행해보겠다.
구현할 코드를 크게 세 부분으로 나누면,
1. FCM 인증 및 초기 설정
2. 알림 구현
3. Firebase Token 발급
으로 나눌 수 있다.
먼저 구현에 앞서 패키지를 설치하겠다.
firebase_core: ^2.8.0
firebase_messaging: ^14.3.0
flutter_local_notifications: ^13.0.0
패키지 설치 및 프로젝트 - Firebase 연결은 어렵지 않아 생략하도록 하겠다.
fcmSetting.dart
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<String?> fcmSetting() async {
// firebase core 기능 사용을 위한 필수 initializing
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
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}');
// foreground에서의 푸시 알림 표시를 위한 알림 중요도 설정 (안드로이드)
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'somain_notification',
'somain_notification',
description: '소마인 알림입니다.',
importance: Importance.max
);
// foreground 에서의 푸시 알림 표시를 위한 local notifications 설정
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel);
// foreground 푸시 알림 핸들링
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification?.title,
notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: android.smallIcon,
),
));
print('Message also contained a notification: ${message.notification}');
}
});
// firebase token 발급
String? firebaseToken = await messaging.getToken();
print("firebaseToken : ${firebaseToken}");
return firebaseToken;
}
푸시 알림이 오는 상황은 Foreground, Background 두 가지로 구분할 수 있다.
간단하게 앱이 실행중일 때는 Foreground, 앱이 꺼져있거나 background로 실행중일 때 Background 상태이다.
위 두 상황에 대해 FCM은 각기 다른 핸들러를 사용한다. Background의 경우는 따로 핸들러를 구현해주지 않고 FCM initializing만 해줘도 된다.
하지만 Foreground의 경우 (앱이 기기 화면의 최상단에서 실행 중인 경우) 별도의 핸들러를 구현해야한다.
또 안드로이드의 경우 Foreground 상태에서 알림을 보내지 않도록 정책이 되어있기에 알림의 중요도를 따로 설정해줘야한다.
이를 위해서 외부 라이브러리인 flutter_local_notifications 를 사용한다. 이는 공식문서에서도 가이드해주고 있는 부분이다.
해당 라이브러리는 서버 없이 local 단에서 알림을 주는 패키지인데, 안드로이드에서 중요도를 설정해 Foreground 상태에서도 알림을 주게 할 수 있다.
위 코드에서 맨 아래쪽은 Firebase Token을 발급하여 리턴하는 코드이다.
이 토큰으로 알림을 보낼 유저를 특정해낼 수 있다.
위 코드는 main에서 runApp이 실행되기 전에 불러와야한다.
void main() async {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
// notification 설정
String? firebaseToken = await fcmSetting();
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: WebViewScreen(
firebaseToken: firebaseToken,
),
),
);
}
필자는 위와 같이 firebaseToken을 받은 후, statefulwidget에 넘겨주었다.
그리고 해당 위젯에서 서버로 넘겨주는 로직을 구현하였다. (firebaseToken 등록용 별도의 백엔드 api 필요)
마지막으로 AndroidManifest.xml을 수정해준다.
<!-- 알림 받기 -->
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver" android:exported="false" />
<!-- Notification -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="somain_notification" />
위 태그는 <application> 태그 안에 넣어주면 된다.
ios의 경우는 xcode를 설정해야한다. 아래 공식 문서를 참고하길 바란다.
이제 토큰을 가지고 알림을 보내면 수신할 수 있다.
알림을 보내는 구체적인 백엔드 구현은 아래 링크에서 확인할 수 있다.
'Mobile Front > Flutter' 카테고리의 다른 글
[Flutter] webview 양방향 통신 (flutter webview two way communication) (0) | 2023.03.19 |
---|---|
[Flutter] 웹뷰 뒤로가기 구현 (+ 앱 종료시 다이얼로그 띄우기) (webview_flutter 4.0.0 버전) (1) | 2023.01.26 |