feat: Enable Firebase Cloud Messaging for iOS with platform-specific configurations and update Android build settings.
This commit is contained in:
@@ -12,6 +12,7 @@ android {
|
||||
ndkVersion = flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
@@ -55,6 +56,10 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
import FirebaseMessaging
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
@@ -10,4 +11,13 @@ import UIKit
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
// Forward APNs token to Firebase for FCM
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
||||
) {
|
||||
Messaging.messaging().apnsToken = deviceToken
|
||||
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:real_estate_mobile/config/app_config.dart';
|
||||
|
||||
@@ -5,44 +7,68 @@ class FirebaseConfig {
|
||||
static FirebaseOptions get currentOptions {
|
||||
switch (AppConfig.flavor) {
|
||||
case Flavor.dev:
|
||||
return _dev;
|
||||
return Platform.isIOS ? _devIos : _devAndroid;
|
||||
case Flavor.demo:
|
||||
return _demo;
|
||||
return Platform.isIOS ? _demoIos : _demoAndroid;
|
||||
case Flavor.local:
|
||||
return _local;
|
||||
return Platform.isIOS ? _localIos : _localAndroid;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Dev ──
|
||||
static const _dev = FirebaseOptions(
|
||||
apiKey: 'AIzaSyAwb_9fc7n9gbN_IQqWeYRkHSSykzVHCyc', // Android
|
||||
// ── Dev (Android) ──
|
||||
static const _devAndroid = FirebaseOptions(
|
||||
apiKey: 'AIzaSyAwb_9fc7n9gbN_IQqWeYRkHSSykzVHCyc',
|
||||
appId: '1:703616926518:android:4342b796fbabb690fca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
iosBundleId: 'com.requestn.realEstateMobile.dev',
|
||||
iosClientId: null,
|
||||
);
|
||||
|
||||
// ── Demo ──
|
||||
static const _demo = FirebaseOptions(
|
||||
// ── Dev (iOS) ──
|
||||
static const _devIos = FirebaseOptions(
|
||||
apiKey: 'AIzaSyD67KPio-70XW_yGjrRUyq9ejdZoZA1rmE',
|
||||
appId: '1:703616926518:ios:301cac94994fbdc3fca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
iosBundleId: 'com.requestn.realEstateMobile.dev',
|
||||
);
|
||||
|
||||
// ── Demo (Android) ──
|
||||
static const _demoAndroid = FirebaseOptions(
|
||||
apiKey: 'AIzaSyAwb_9fc7n9gbN_IQqWeYRkHSSykzVHCyc',
|
||||
appId: '1:703616926518:android:270639d6887d2cb4fca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
iosBundleId: 'com.requestn.realEstateMobile.demo',
|
||||
iosClientId: null,
|
||||
);
|
||||
|
||||
// ── Local ──
|
||||
static const _local = FirebaseOptions(
|
||||
// ── Demo (iOS) ──
|
||||
static const _demoIos = FirebaseOptions(
|
||||
apiKey: 'AIzaSyD67KPio-70XW_yGjrRUyq9ejdZoZA1rmE',
|
||||
appId: '1:703616926518:ios:2d2f7d163774722dfca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
iosBundleId: 'com.requestn.realEstateMobile.demo',
|
||||
);
|
||||
|
||||
// ── Local (Android) ──
|
||||
static const _localAndroid = FirebaseOptions(
|
||||
apiKey: 'AIzaSyAwb_9fc7n9gbN_IQqWeYRkHSSykzVHCyc',
|
||||
appId: '1:703616926518:android:2eb242f07b174c25fca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
);
|
||||
|
||||
// ── Local (iOS) ──
|
||||
static const _localIos = FirebaseOptions(
|
||||
apiKey: 'AIzaSyD67KPio-70XW_yGjrRUyq9ejdZoZA1rmE',
|
||||
appId: '1:703616926518:ios:15652d299f9f2d7ffca997',
|
||||
messagingSenderId: '703616926518',
|
||||
projectId: 'real-estate-2d71e',
|
||||
storageBucket: 'real-estate-2d71e.firebasestorage.app',
|
||||
iosBundleId: 'com.requestn.realEstateMobile.local',
|
||||
iosClientId: null,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,16 +30,8 @@ class PushNotificationService {
|
||||
void Function(String? actionUrl)? onNotificationTap;
|
||||
|
||||
/// Initialize Firebase Messaging and local notifications.
|
||||
/// Skipped on iOS until Firebase iOS app is configured.
|
||||
Future<void> initialize() async {
|
||||
if (_initialized) return;
|
||||
|
||||
// Skip on iOS — no Firebase iOS app configured yet
|
||||
if (Platform.isIOS) {
|
||||
debugPrint('[FCM] Skipped on iOS — no Firebase iOS app configured');
|
||||
return;
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
|
||||
_messaging = FirebaseMessaging.instance;
|
||||
@@ -188,7 +180,7 @@ class PushNotificationService {
|
||||
|
||||
/// Unregister FCM token from backend (call on logout).
|
||||
Future<void> unregister() async {
|
||||
if (Platform.isIOS || _currentToken == null) return;
|
||||
if (_currentToken == null) return;
|
||||
try {
|
||||
await _repo.removeFcmToken(_currentToken!);
|
||||
debugPrint('[FCM] Token unregistered from backend');
|
||||
@@ -200,7 +192,6 @@ class PushNotificationService {
|
||||
|
||||
/// Re-register token after login.
|
||||
Future<void> registerAfterLogin() async {
|
||||
if (Platform.isIOS) return;
|
||||
await _getAndRegisterToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,7 @@ Future<void> mainCommon(Flavor flavor) async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await AppConfig.init(flavor);
|
||||
|
||||
// Initialize Firebase — iOS may fail if no iOS app configured in Firebase Console
|
||||
try {
|
||||
await Firebase.initializeApp(options: FirebaseConfig.currentOptions);
|
||||
} catch (e) {
|
||||
debugPrint('[Firebase] Init failed (expected on iOS without config): $e'); // ignore: avoid_print
|
||||
}
|
||||
await Firebase.initializeApp(options: FirebaseConfig.currentOptions);
|
||||
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user