import "package:flutter/foundation.dart"; import "package:firebase_core/firebase_core.dart"; import "package:firebase_messaging/firebase_messaging.dart"; /// FCM 푸시 서비스. /// /// Firebase 설정(google-services.json / GoogleService-Info.plist + firebase_options) /// 이 아직 없으면 `Firebase.initializeApp()` 이 실패하므로 try/catch로 감싸고 비활성 /// 상태로 동작한다 (앱은 정상 실행). 설정이 추가되면 자동으로 토큰을 얻는다. class PushService { PushService._(); static final PushService instance = PushService._(); bool enabled = false; /// 현재 FCM 토큰 (없으면 null). 웹뷰 로드 후 web으로 전달해 /api/devices 에 등록. final ValueNotifier token = ValueNotifier(null); /// 푸시 탭으로 진입했을 때 이동할 in-app 경로(예: "/inbox"). 웹뷰가 소비. final ValueNotifier pendingLink = ValueNotifier(null); Future init() async { try { await Firebase.initializeApp(); } catch (e) { debugPrint("push: Firebase 미설정 — 푸시 비활성 ($e)"); enabled = false; return; } enabled = true; final messaging = FirebaseMessaging.instance; try { await messaging.requestPermission(alert: true, badge: true, sound: true); token.value = await messaging.getToken(); messaging.onTokenRefresh.listen((t) => token.value = t); // 앱이 종료 상태에서 푸시 탭으로 실행된 경우 final initial = await messaging.getInitialMessage(); if (initial != null) _consume(initial); // 백그라운드에서 푸시 탭으로 복귀 FirebaseMessaging.onMessageOpenedApp.listen(_consume); } catch (e) { debugPrint("push: init 오류 $e"); } } void _consume(RemoteMessage m) { final link = m.data["link"]; if (link is String && link.isNotEmpty) pendingLink.value = link; } }