본문 바로가기

Flutter

[Flutter] Firebase FCM 사용하기 Part. 2 (Android)

728x90

 

Part.2 시작하겠습니다. 

 

https://firebase.flutter.dev/docs/messaging/overview

 

Firebase Cloud Messaging | FlutterFire

What does it do?

firebase.flutter.dev

공식문서를 참고하시길 바랍니다.

 

 

1. android/build.gradle 파일의 plugins 추가.

 

1-1. flutterfire configure 할 때 (Part.1 참고) 추가가 되기 때문에 확인만 하시면 됩니다. 만약 안 되어있으면 추가. 

id "com.google.gms.google-services" version "4.3.15" apply false

 

2. android/app/build.gradle 파일의 plugins 추가 

2-1. flutterfire configure 할 때 (Part.1 참고) 추가가 되기 때문에 확인만 하시면 됩니다. 만약 안 되어있으면 추가. 

id 'com.google.gms.google-services'

 

3. AndroidManifest 추가 

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="USE_FULL_SCREEN_INTENT"/>

 

 

<application
.
.

	 <activity
     .
     .
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="channer_id" />
     .
     .
     </activity>
     
</application>

 

 

 

4. lib 안에 파일에 FirebaseApi dart 파일 추가 

import 'dart:convert';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class FirebaseApi {
  // Firebase Messaging 인스턴스 생성
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;

  // Android Notification Channel 설정
  final AndroidNotificationChannel _androidChannel =
      const AndroidNotificationChannel(
    'high_importance_channel',
    'High Importance Notifications',
    description: 'This channel is used for important notifications',
    importance: Importance.high,
  );

  final FlutterLocalNotificationsPlugin _localNotifications =
      FlutterLocalNotificationsPlugin();

  // Notification 초기화
  Future<void> initNotifications() async {
    // 사용자에게 권한 요청
    await _firebaseMessaging.requestPermission();

    // FCM 토큰 가져오기
    final String? fcmToken = await _firebaseMessaging.getToken();
    print('FCM Token: $fcmToken');

    // 푸시 알림 초기화
    await initPushNotifications();
    await initLocalNotification();
  }

  // 로컬 알림 초기화
  Future<void> initLocalNotification() async {
    const AndroidInitializationSettings android =
        AndroidInitializationSettings('@mipmap/ic_launcher'); // mipmap
    const InitializationSettings settings =
        InitializationSettings(android: android);

    await _localNotifications.initialize(settings);

    final AndroidFlutterLocalNotificationsPlugin? platform =
        _localNotifications.resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>();

    await platform?.createNotificationChannel(_androidChannel);
  }

  // 메시지 수신 처리
  void handleMessage(RemoteMessage? message) {
    if (message == null) return;

    print('Received message: $message');
  }

  // 푸시 알림 초기화
  Future<void> initPushNotifications() async {
    FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage);

    await FirebaseMessaging.instance
        .setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );

    // 앱이 종료된 상태에서 메시지 클릭 시 처리
    FirebaseMessaging.instance.getInitialMessage().then(handleMessage);

    // 앱이 실행 중일 때 메시지 클릭 시 처리
    FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);

    // 포그라운드에서 메시지 수신
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      final notification = message.notification;
      if (notification != null) {
        _localNotifications.show(
          notification.hashCode,
          notification.title,
          notification.body,
          NotificationDetails(
            android: AndroidNotificationDetails(
              _androidChannel.id,
              _androidChannel.name,
              channelDescription: _androidChannel.description,
              icon: '@mipmap/ic_launcher', // mipmap 있는 아이콘
            ),
          ),
          payload: jsonEncode(message.data), // 메시지 데이터
        );
      }
    });
  }

  Future<void> handleBackgroundMessage(RemoteMessage message) async {
    print('Background message received:');
    print('Title: ${message.notification?.title}');
    print('Body: ${message.notification?.body}');
    print('Data: ${message.data}');
  }
}

 

 

 

 

5. lib main.dart 수정

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  try {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
    await FirebaseApi().initNotifications();
  } catch (e) {}
  
  runApp();
}

 

 

참고 https://gwpaeng.tistory.com/509