본문 바로가기

일::개발

Flutter Push Notification (3) - 푸시 알림 터치해서 페이지 이동하기

 

예정은 이것이 아니었지만, 알림 메시지를 터치해서 특정한 동작(ex. 해당 페이지로 이동)하는 방법을 먼저 정리해본다.

 

간단해 보이지만, 생각보다 해야할 것이 많다.

앱이 Foreground 일 때, Background 일 때, Terminated 일때, 각각 상태에 따라 별도로 구현을 해줘야 하는데, 간단한 순서로 만들어보자.

 

1) Foreground 일 때

Foreground 상태에서는 flutter_local_notification 패키지를 이용해서 heads up notification 을 만들어주었기 때문에, local notification 에서 처리해줘야 한다.

 

일단 flutterLocalNotificationsPlugin.show() 에서 payload 파라미터에 원하는 값(Push Notification을 통해 전달하려는 값)을 넣어준다.

       flutterLocalNotificationsPlugin.show(
          0,
          notification.title,
          notification.body,
          NotificationDetails(
            android: AndroidNotificationDetails(
              'high_importance_channel', // 임의의 id
              'High Importance Notifications', // 설정에 보일 채널명
              'This channel is used for important notifications.', // 설정에 보일 채널 설명
              // other properties...
            ),
          ),
          // 여기서는 간단하게 data 영역의 임의의 필드(ex. argument)를 사용한다.
          payload: rm.data['argument'],
        );

여기서는 간단하게 data 영역에 'argument' 라는 항목을 만들어서 사용하는데, 필요하다면 RemoteMessage 객체를 통해 전달되는 어떤 값을 사용해도 상관 없다. 단 payload 는 String 타입.

 

data 영역에 custom parameter를 넣어서 보내려면 Firebase Console 에서는 아래와 같이 해 주면 'Sample Argument'라는 스트링이 전달된다.

이렇게 하면 payload를 가진 local notification 이 화면에 보이게 되고, 이것을 터치했을 때의 동작은 flutterLocalNotificationsPlugin.initialize() 에서 정의해준다.

    await flutterLocalNotificationsPlugin.initialize(
        InitializationSettings(
            android: AndroidInitializationSettings('@mipmap/ic_launcher'),
            iOS: IOSInitializationSettings()),
        onSelectNotification: (String? payload) async {
        
      // Foreground 에서 수신했을 때 생성되는 heads up notification 클릭했을 때의 동작
      Get.to(NotificationDetailsPage(), arguments: payload);
    });

예제에서는 특정한 페이지로 해당 payload를 가지고 이동하도록 했다.

필요하다면 여기서 payload를 보고 필요한 페이지로 분기하면 되겠다.

 

 

 

2) Background일 때

Background 상태에서 Notification을 터치했을 때의 기본 동작은 앱을 Foreground로 전환하는 것이다.

터치했을 때 원하는 동작을 하려면 FirebaseMessaging.onMessageOpenedApp.listen() 에서 처리해주면 된다.

예전 버전에서는 configure(onBackgroundMessage: ....) 이렇게 했었는데, Firebase API가 변경되면서

FirebaseMessaging.onMessageOpenedApp.listen() 에 콜백을 등록하면 된다.

    // background 상태. Notification 서랍에서 메시지 터치하여 앱으로 돌아왔을 때의 동작은 여기서.
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage rm) {
      Get.to(NotificationDetailsPage(), arguments: rm.data['argument']);
    });

 

 

3) Terminated일 때

앱이 완전히 종료된 상태(Terminated)에서 역시 Notification을 터치했을 때의 기본 동작은 앱 실행이다.

이 때는 좀 더 고려해야할 것이 있는데, 앱 실행에 필요한 초기화 과정 등을 거친 후에 메시지에 정의된 동작을 해야 하기 때문이다.

 

이를 위해 앱 최초 실행 시에 도착한 메시지가 있는지 확인해보고 있으면 정해진 동작을 하도록 해보자.

 

초기화가 끝난 후에 FirebaseMessaging.instance.getInitialMessage() 를 호출해본다. 종료된 상태에서 푸시 알림을 터치해서 앱이 실행이 되었다면 RemoteMessage 객체가 반환된다.

(푸시 알림이 도착했어도 앱을 직접 실행했다면 null 이 반환된다.)

    // Terminated 상태에서 도착한 메시지에 대한 처리
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();
    if (initialMessage != null) {
      Get.to(NotificationDetailsPage(),
          arguments: initialMessage.data['argument']);
    }

 

이렇게 해주면 안드로이드, iOS 모두 Foreground, Background, Terminated 상태에서 수신된 푸시 알림 터치했을 때 원하는 동작을 할 수 있다.

여기까지의 소스는 https://github.com/nicejhkim/flutter_fcm_sample 에 올려두었다.