본문 바로가기

✏️/Flutter

[flutter] local notification - FCM foreground 처리하기

728x90

ㅎ2ㅎ2
오늘은 local notification 설정에 대해서 이야기 할 예정이다.

 

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

Local notification

- 앱이 foreground 상태일 때 알림을 받게 해주려면 설정이 필요하다.
- 그것이 바로 Local notification 설정이고, 앱이 foreground 상태일 때 콜백을 따로 받아 알림 처리를 해줘야하기 때문이다.

flutter로 앱을 개발할 경우, 알림 관련해서 firebase_messaging 플러그인을 통해서 구현하는데, 
파베 플러그인으로 알림을 구현한 경우 background 상태에서만 알림이 오는 것을 확인 할 수 있을 것이다.

바로.. iOS와 AOS가 푸시 동작하는데 있어서 다른 구조로 되어 있어, foreground 푸시를 원할 경우 따로 설정을 해줘야한다.

따라서 이 글은 firebase_messaging 이 되어 있는 경우, 어떻게 설정하는지에 대해서 이야기 해보겠다~~~


0. flutter Setup 

가볍~~게 플러그인 하나 달아주고 ~ 시작해보잣!!!!!!

# pubspec.yaml 
# flutter v.1.22 기준

dependencies:
  flutter_local_notifications: ^4.0.1+2

 

1.  Android Setup 

AndroidMenifest.xml

<activity
    android:name=".MainActivity"
    ...
    
    android:showWhenLocked="true"
    android:turnScreenOn="true">

: 잠겨 있을 때도 활성화될 수 있도록 설정

    <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" />

: 부팅 시 서비스 실행, 진동, 알림 오면 화면 열리기, full screen 인텐트 사용 허용

<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
    <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
    </intent-filter>
</receiver>

: flutterlocalnotification 스케줄러 리시버 등록

Application.kt

import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin
import io.flutter.view.FlutterMain
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin

class Application : FlutterApplication(), PluginRegistrantCallback {

    override fun onCreate() {
        super.onCreate()
        FlutterFirebaseMessagingService.setPluginRegistrant(this); // 기존 파베 코드
        FlutterMain.startInitialization(this) // 추가!
    }
    
    // 파베 메시징이랑 local noti 플러그인 연동
    override fun registerWith(registry: PluginRegistry?) {
        FirebaseMessagingPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
        FlutterLocalNotificationsPlugin.registerWith(registry!!.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"));
    }
}

 

2.  iOS Setup 

AppDelegate.swift

..
override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

...

: iOS 10부터 여러 앱에서 푸시 알림을 UserNotificationCenter에서 관리를 하는데, 관련해서 알림 권한 설정에 관한 코드

 

3.  Flutter code!

파베 메시징 되어있는 코드 단으로 이동해서.. local notification을 플랫폼(AOS, iOS)별로 설정해주면 끝이다.
(정말 코드단에서 뭐 할게 없다..)

// 파이어베이스 메시징 설정하는 코드
firebaseMessaging.configure(
	// 포그라운드 콜백
    onMessage: (Map<String, dynamic> message) async {
    	_showNotification(message); // Local Notification 실제 처리 코드
    },
    
    // 백그라운드 콜백
    onBackgroundMessage: ...
    // 앱 종료 콜백
    onLaunch: ..
    // 앱 종료되었지만, 백그라운드에 있는 경우
    onResume: .. 
);


Future _showNotification(message) async {
    String title, body;

    // AOS, iOS에 따라 message 오는 구조가 다르다. (직접 파베 찍어보면 확인 가능)
    if(Platform.isAndroid){
      title = message['notification']['title'];
      body = message['notification']['body'];
    }
    if(Platform.isIOS){
      title = message['aps']['alert']['title'];
      body = message['aps']['alert']['body'];
    }

    // AOS, iOS 별로 notification 표시 설정 
    var androidNotiDetails = AndroidNotificationDetails('dexterous.com.flutter.local_notifications', title, body, importance: Importance.max, priority: Priority.max);
    var iOSNotiDetails = IOSNotificationDetails();

    var details = NotificationDetails(android: androidNotiDetails, iOS: iOSNotiDetails);

    await flutterLocalNotificationsPlugin.show(0, title, body, details
	// 0은 notification id 값을 넣으면 된다.
}
@override
void initState() {
   super.initState();
   ...
   
   _localNotiSetting(); // Local notificiatioin 초기 설정
}

void _localNotiSetting() async {
    var androidInitializationSettings =AndroidInitializationSettings('@mipmap/ic_launcher');
    // 안드로이드 알림 올 때 앱 아이콘 설정
    
    var iOSInitializationSettings = IOSInitializationSettings(
        requestAlertPermission: true,
        requestBadgePermission: true,
        requestSoundPermission: true);
	// iOS 알림, 뱃지, 사운드 권한 셋팅
    // 만약에 사용자에게 앱 권한을 안 물어봤을 경우 이 셋팅으로 인해 permission check 함

    var initsetting = InitializationSettings(
        android: androidInitializationSettings, iOS: iOSInitializationSettings);

    await flutterLocalNotificationsPlugin.initialize(initsetting);
}

 

각 플랫폼 별로 메시지를 따로 처리해야한다는 것에 유의하는게 포인트이다!
이렇게 파베 부분, 알림 권한 부분 2곳만 하면 끝~~~~~ (간단)

하지만... 뱃지 알림은 또 또또 따로 설정해줘야한다 ^^.. 담에 성공하면 글 쓰러 오겠다....

--
https://pub.dev/packages/flutter_local_notifications#custom-notification-icons-and-sounds

https://medium.com/flutterdevs/local-push-notification-in-flutter-763605b84985

https://eory96study.tistory.com/26