[FCM/Flutter] Firebase Functions 사용해서 FCM 푸시알람 구현하기 1/3 - FCM 구현

찌니·2023년 7월 25일
1

Fcm+Functions

목록 보기
1/3

본인은 FCM과 Firebase Functions를 사용해서 사용자에게 푸시 알람을 보내는 것을 목표로 합니당

Android Setting

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<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" />

<application
	<activity>
      <intent-filter>
        <action android:name="FLUTTER_NOTIFICATION_CLICK" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
     </activity>
     
     <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="high_importance_channel"
      />

Ios Setting

역시나 설정할게 많은 ios... 먼저 Ios는 에뮬레이터에서 푸시알람이 오지 않기 때문에 실 기기에서 테스트 해야하고, APN 인증키를 필요로 합니다.

IOS APN 인증서 발급 및 등록하기!

위 글에 추가로 푸시 알림을 위해 Background Modes도 Xcode에서 설정해준다.

필요 라이브러리 : firebase_messaging, flutter_local_notifications

main.dart

// 백그라운드 설정 코드는 맨 최상단에 위치해야함
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  print('Handling a background message ${message.messageId}');
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  fcmSetting();

  
  runApp(const ProviderScope(child: MyApp()));
}

Future<void> fcmSetting() async { 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,
  );

  const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'high_importance_channel', // id
      'High Importance Notifications',
      description: 'This channel is used for important notifications.',
      importance: Importance.high,
      playSound: true);
      
  var initialzationSettingsIOS = const DarwinInitializationSettings(
    requestSoundPermission: true,
    requestBadgePermission: true,
    requestAlertPermission: true,
  );

  var initializationSettingsAndroid = const AndroidInitializationSettings('@mipmap/launcher_icon');
  
  var initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initialzationSettingsIOS);
  final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
      AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
      
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          IOSFlutterLocalNotificationsPlugin>()
      ?.getActiveNotifications();

  await flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
  );

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    RemoteNotification? notification = message.notification;
    AndroidNotification? android = message.notification?.android;

    if (message.notification != null && android != null) {
      flutterLocalNotificationsPlugin.show(
        notification.hashCode,
        notification?.title,
        notification?.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
            icon: '@mipmap/launcher_icon',
          ),
        ),
      );
    }
  });
  
  // 토큰 발급
  var fcmToken = await FirebaseMessaging.instance.getToken()
  
  // 토큰 리프레시 수신
  FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async {
  // save token to server
});
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: SplashScreen(),
    );
  }
}

Firebase Console에서 바로 테스트도 가능하다!!

profile
찌니's develog

1개의 댓글

comment-user-thumbnail
2023년 8월 24일

백엔드 개발자가 Flutter 개발 중인데ㅠㅠ 큰 도움이 됐습니다!!
감사합니다~

답글 달기