ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Flutter / 플러터 ] 삽질은 그만, Firebase Messaging 안드로이드 셋업
    개발일지/flutter 2021. 4. 4. 19:00

    안녕하세요 개발하는남자 개남입니다. 

    오늘은 파이어베이스 cloud messaging를 플러터로 어떻게 설정하고 구현하는지를 기록하는 포스팅입니다.

     

    정말… 매번 느끼는 것이지만 ;; 

    할 때마다 늘 새로운 것 같습니다. 

    분명 지난번 앱 개발할 때 개발을 했음에도 불구하고 

    다시 새로운 앱을 세팅하려고 하면 머릿속이 새하얀 도화지가 된 마냥 어찌 이렇게 깨끗한지 ~ 

    항상 신기하면서도 제 스스로가 못났다는 생각을 하게 됩니다.

    이제는 그런 삽질을 덜고자 이렇게 나만의 문장, 나만의 스타일로 (미래의 나에게)

    이렇게 도움이 되는 포스팅을 남기려 합니다.

    사용된 소스는 아래 github에 있습니다. 

     

    sudar-life/flutter_firebase_cloud_messaging_sample

    파이어베이스 메세지 세팅을 위한 최소한의 구조 (with Getx). Contribute to sudar-life/flutter_firebase_cloud_messaging_sample development by creating an account on GitHub.

    github.com


    안드로이드 세팅 먼저 시작합니다.

     

    1. 플러터 프로젝트를 생성합니다.

    flutter create fire_notification_sample

    생성된 프로젝트를 VSCode로 실행해줍니다.

     

     

    2. 필요한 라이브러리 세팅 

    pubspec.yaml파일에 필요한 라이브러리를 추가합니다.

    라이브러리는 물론 pub.dev 사이트에서 찾을 수 있습니다.

      firebase_core: "0.5.3"
      firebase_messaging: "7.0.3"
      get: ^3.24.0

     

    참고로 작성일 기준 플러터가 2.0.3 이 release 되었지만 호환성 문제로 2020년 12월 기준의 버전으로 세팅한 것입니다. 

     

     

    3. 소스 코드 작성 

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          initialBinding: BindingsBuilder(
            () {
              Get.put(NotificationController());
            },
          ),
          home: Scaffold(
            appBar: AppBar(),
            body: Obx(() {
              if (NotificationController.to.message.isNotEmpty) // 원하는 페이지 or 이벤트 처리 
              return Container();
            }),
          ),
        );
      }
    }

    상태 관리는 당연 Getx를 사용할 것이기에 GetMaterialApp으로 감쌓아 줬습니다.

    만일 Getx가 무엇인지 모르신 다면? 아래의 포스트를 참고해주시면 됩니다. (플러터 상태관리 단연 최고!)

     

     

    [ flutter ]상태관리의 끝판왕? GetX를 정리해 보았다.

    안녕하세요 개발하는 남자 개남입니다 :) 오늘은 GetX에 대해 정리하는 포스팅을 써보려고 합니다. 처음 플러터로 개발하면서 상태 관리를 위해 접했던 것이 bloc이었습니다. 그 당시 정말 강력하

    sudarlife.tistory.com

    위 소스에 initalBinding으로 최초 앱이 실행될 때 NotificationController 리소스를 올렸습니다. 

    NotificationController 소스는 아래와 같습니다

    import 'package:firebase_messaging/firebase_messaging.dart';
    import 'package:get/get.dart';
    import 'package:get/get_state_manager/get_state_manager.dart';
    
    class NotificationController extends GetxController {
      static NotificationController get to => Get.find();
      FirebaseMessaging _messaging = FirebaseMessaging();
      RxMap<String, dynamic> message = Map<String, dynamic>().obs;
    
      @override
      void onInit() {
        _initNotification();
        _getToken();
        super.onInit();
      }
    
      Future<void> _getToken() async {
        try {
          String token = await _messaging.getToken();
          print(token);
        } catch (e) {}
      }
    
      void _initNotification() {
        _messaging.requestNotificationPermissions(const IosNotificationSettings(
            sound: true, badge: true, alert: true, provisional: true));
    
        _messaging.configure(
          onMessage: _onMessage,
          onLaunch: _onLaunch,
          onResume: _onResume,
        );
      }
    
      Future<void> _onResume(Map<String, dynamic> message) {
        print("_onResume : $message");
        return null;
      }
    
      Future<void> _onLaunch(Map<String, dynamic> message) {
        print("_onLaunch : $message");
        _actionOnNotification(message);
        return null;
      }
    
      void _actionOnNotification(Map<String, dynamic> messageMap) {
        message(messageMap);
      }
    
      Future<void> _onMessage(Map<String, dynamic> message) {
        print("_onMessage : $message");
        return null;
      }
    }
    

    소스 설명은 따로 유튜브 영상에서 코드 작성하면서 다루도록 하겠습니다. 

    대충 이렇게 코드를 작성해주면 이제 메시지 처리는 소스상에서는 끝이 났습니다. 

    사실 ,, 푸시 메시지는 세팅이 거의 8할이라고 생각이 됩니다. 

    그리고 안드로이드가 8할 중 2할 정도이고 나머지 6할이 IOS라는 사실 =ㅁ=;; 

    정말.. 복잡스럽습니다. (iOS) 관련 내용은 iOS 세팅하는 포스팅에서 다뤄보도록 하겠습니다.

     

     

     

    4. 파이어베이스 안드로이드 세팅

    자 그럼 상대적으로 쉬운 android 먼저 세팅하겠습니다.

    가장 먼저 firebase console에서 프로젝트를 생성합니다.

     

    프로젝스 생성 후 내부로 들어가면 iOS / Android를 세팅할 아이콘이 보입니다.

    안드로이드 아이콘을 선택해줍니다.

     

    패키지명만 추가하면 됩니다 앱 닉네임, 디버그 서명의 경우 cloud messaging에서는 필수 요소가 아니기에 빈 값으로 넣어도 무방합니다.

    하지만 아무래도 테스트 버전이 아닌 앱 개발을 위한 세팅이라면 채워 주시는 것이 좋습니다.

     

    Google-services.json파일을 다운로드하여 app 폴더 하위에 넣어줍니다

    그림에 아주 친절하게 설명이 되어있으니 무리 없을 것입니다.

    다음을 눌러주시면 이제 build.gradle에 추가해야 할 소스가 보이는데 아래 내용을 채워주시면 됩니다.

     

    <project>/build.gradle 파일에 dependencies에 아래 소스만 추가

    classpath 'com.google.gms:google-services:4.3.3'

    <project>/<app>/build.gradle

    apply plugin: 'com.google.gms.google-services’
    
    defaultConfig {
            ...
            minSdkVersion 16
            targetSdkVersion 29
            multiDexEnabled true // 이부분 추가 중요한것은 minSdkVersion 이 21 이상인 경우 필요 없습니다.
            ...
        }
    
    dependencies {
      implementation 'com.android.support:multidex:1.0.3'
    }

    이제 안드로이드는 기본 세팅은 끝이 났습니다.

    이제 바로 메시지를 받을수 있는 상태가 된 것입니다.


    옵션 1 )

    메시지 받는데에는 문제가 없지만 아마 메세지 팝업이 앱이 꺼진 상태와, 앱이 백그라운드 모드로 돌고 있을때에 디바이스 상단에 

    메세지 팝업이 띄워지기를 원하는 분들이 있을 것입니다. 그것을 위해 아까 소스 중에 flutter_local_notifications 라이브러리는 추가해 줬습니다. 

     

    자 그럼 팝업을 띄우기 위해 AndroidManifest.xml파일에 추가 설정을 해줍니다.

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

    그리고 @string/default_notification_channel_id의 값을 추가해줘야 합니다.

    경로는 <project>/android/app/src/main/res/values/strings.xml입니다.

    아마 플러터 프로젝트를 만들었기 때문에 strings.xml 파일이 없을 가능성이 많습니다.

    당황하지 말고 strings.xml파일을 만들어줍니다.

    그리고 다음과 같이 내용을 추가해 줍니다.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="default_notification_channel_id" translatable="false">sample_channel_id</string>
    </resources>

    여기서 sample_channel_id라는 값으로 제가 만들어 준 것입니다. 이 부분은 소스 코드 controller에 _showNotification이라는 함수 내에서 사용하고 있습니다. 

    ...
    void _showNotification(Map<String, dynamic> message) async {
        NotificationDetails notificationDetails = NotificationDetails(
            android: AndroidNotificationDetails(
                "sample_channel_id", "Notification Test", ""),
            iOS: IOSNotificationDetails());
        await _flutterLocalNotificationsPlugin.show(
          0,
          message["title"],
          message["body"],
          notificationDetails,
          payload: json.encode(message["data"]),
        );
    }
    ...

    이렇게 추가해줘야 하는 이유에 대해서는 firebase 문서에 설명되어있습니다. 그 부분을 발췌 한 내용은 아래 내용입니다.

    • (선택사항) Android 8.0(API 수준 26) 이상부터는 알림 채널이 지원 및 권장됩니다. FCM은 기본적인 설정으로 기본 알림 채널을 제공합니다. 기본 채널을 직접 만들어 사용하려면 아래와 같이 default_notification_channel_id를 알림 채널 객체의 ID로 설정합니다. 받은 메시지에 명시적으로 설정된 알림 채널이 없으면 FCM에서는 항상 이 값을 사용합니다. 자세한 내용은 알림 채널 관리를 참조하세요.

    전체 문서는 여기에서 확인 가능합니다.

     

     

    옵션 2 )
    사용자가 툴팁 메시지를 클릭했을 때 단순 앱이 켜지기만 원한다면 따로 설정해 줄 것은 없지만,

    만일 앱 내의 특정한 페이지로 이동시키기를 원한다면 다음 설정을 AndroidManifest.xml 에 추가해줘야 합니다.

    <intent-filter>
        <action android:name="FLUTTER_NOTIFICATION_CLICK" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>

    그리고 firebase console에서 메시지를 보낼 때 추가 옵션에 click_action 키 값과 value 값으로 FLUTTER_NOTIFICATION_CLICK를 담아서 보내줘야 합니다. 이 부분에 대해서는 메시지 푸시 파트에서 다시한번 언급하겠습니다.

     


    메세지 보내기

    이제 메시지를 보내봅시다 firebase console로 접속합니다. 

    좌측 메뉴 중 최하단으로 내리면 참여 파트에 Cloud Messaging이라는 항목이 보입니다 클릭해서 이동해줍니다.

    새알림을 생성해줍니다.

    메시지 타이틀과 알림 텍스트를 입력해주면 옆에 IOS와 Android 가 어떻게 노출되는지를 보여줍니다.

    알림 이미지는 선택사항이니 원하시면 등록해주시면 됩니다. (전 패스)

     

    적당한 제목과 / 텍스트 내용을 채워 주고 다음을 눌러줍니다.

     

     

    앱을 안드로이드로 보낼지 iOS로 보낼 시 선택할 수 있습니다. 안드로이드 선택 

    또한 사용자 세그먼트라는 메뉴 말고 주제라는 메뉴가 있는데 주제라는 메뉴는 주제를 구독한 사람들에게 모두 보낼 수 있습니다( Android, iOS 구별 없이) 예를 들면, 한 달 동안 진행되는 이벤트에 푸시메시지를 받도록 신청하는 파트가 있고 그것을 신청한 사람들에게 메세지를 보내야 하는 때에 사용되면 됩니다.

    다음 , 다음을 눌러주면 됩니다. 

    중요) 위에 설정한 메시지 팝업을 클릭했을 때 특별한 페이지로 이동시키길 원하는 설정을 추가했다면

     

    여기서 맞춤 데이터로 사용됩니다. 

    위에 처럼 세팅하고 검토를 눌러주면 이제 메시지가 날아 올 것입니다.

    발송에는 약간의 지연시간이 있습니다 짧으면 3초에서 길면 2~3분도 걸립니다.

     

    참고로 안드로이드 애뮬레이터에서는 메시지 팝업이 동장 되지 않습니다. 실 기기에서 테스트 해보시면 메세지 팝업이 뜨는 것을 볼 수 있습니다. 단) 안드로이드 의 경우 앱 개별 알림 권한에 대해서 설정을 추가 적으로 해줘야 합니다. 그것은 개별 사람들이 해줘야 하는 부분입니다. 

    위의 처럼 설정이 되어있어야 팝업 메시지가 뜰 것입니다. 

    마지막 이미지의 팝업으로 표시 이 부분을 플러터 소스코드로 접근해서 권한을 허용해주면 참 좋으련만;;; 

    아직 그 방법은 찾지 못했습니다, 혹시 그 방법을 아시는 분이 있다면 아래 댓글로 알려주시면 

    너무너무 감사하겠습니다 ~! 

     

    이상으로 안드로이드에서 파이어베이스 메시지 푸시를 설정하는 방법에 대해 알아보았습니다.

    관련해서 영상으로 보시기 원하시는 분은 제 개남유튜브에서 확인하실 수 있습니다.

    감사합니다.

    댓글

Designed by Tistory.