140 lines
4.2 KiB
Dart
140 lines
4.2 KiB
Dart
import 'dart:io';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// 🔥 FCM Token Manager - Force regenerates token on logout/login
|
|
class FcmTokenManager {
|
|
static final FcmTokenManager _instance = FcmTokenManager._internal();
|
|
factory FcmTokenManager() => _instance;
|
|
FcmTokenManager._internal();
|
|
|
|
final FirebaseMessaging _messaging = FirebaseMessaging.instance;
|
|
|
|
/// 🔑 Get current FCM token
|
|
Future<String?> getCurrentToken() async {
|
|
try {
|
|
if (Platform.isIOS) {
|
|
final apns = await _messaging.getAPNSToken();
|
|
if (apns == null) {
|
|
debugPrint('⚠️ APIs Token missing on iOS - Skipping FCM getToken');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
debugPrint('🔄 Getting current FCM token...');
|
|
final token = await _messaging.getToken();
|
|
debugPrint('✅ Current FCM Token: $token');
|
|
return token;
|
|
} catch (e) {
|
|
debugPrint('❌ Error getting FCM token: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// 🔄 Force regenerate FCM token (deletes old and creates new)
|
|
/// Call this BEFORE login to ensure fresh token
|
|
/// 🔄 Force regenerate FCM token (deletes old and creates new)
|
|
Future<String?> regenerateToken() async {
|
|
try {
|
|
if (Platform.isIOS) {
|
|
final apns = await _messaging.getAPNSToken();
|
|
if (apns == null) {
|
|
debugPrint(
|
|
'⚠️ APIs Token missing on iOS - Cannot regenerate FCM token',
|
|
);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
debugPrint('🔄 Starting FCM token regeneration...');
|
|
|
|
// Step 1: Get old token
|
|
String? oldToken;
|
|
try {
|
|
oldToken = await _messaging.getToken();
|
|
debugPrint('📋 OLD FCM Token: $oldToken');
|
|
} catch (e) {
|
|
debugPrint('⚠️ Could not get old token: $e');
|
|
}
|
|
|
|
// Step 2: Delete the old token
|
|
try {
|
|
debugPrint('🗑️ Deleting old FCM token...');
|
|
await _messaging.deleteToken();
|
|
debugPrint('✅ Old token deleted');
|
|
} catch (e) {
|
|
debugPrint('⚠️ Error deleting old token: $e');
|
|
}
|
|
|
|
// Step 3: Wait
|
|
await Future.delayed(const Duration(milliseconds: 800));
|
|
|
|
// Step 4: Request permission
|
|
await _messaging.requestPermission(alert: true, badge: true, sound: true);
|
|
|
|
// Step 5: Generate new token
|
|
debugPrint('🔄 Generating new FCM token...');
|
|
final newToken = await _messaging.getToken();
|
|
|
|
if (newToken != null) {
|
|
debugPrint('✅ NEW FCM Token: $newToken');
|
|
} else {
|
|
debugPrint('⚠️ Failed to generate new token');
|
|
}
|
|
|
|
return newToken;
|
|
} catch (e) {
|
|
debugPrint('❌ Error regenerating FCM token: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// 🗑️ Delete FCM token (call on logout)
|
|
Future<bool> deleteToken() async {
|
|
try {
|
|
if (Platform.isIOS) {
|
|
final apns = await _messaging.getAPNSToken();
|
|
if (apns == null) return false;
|
|
}
|
|
|
|
// Print token before deletion
|
|
final currentToken = await _messaging.getToken();
|
|
debugPrint('📋 Current FCM Token (before delete): $currentToken');
|
|
|
|
debugPrint('🗑️ Deleting FCM token...');
|
|
await _messaging.deleteToken();
|
|
debugPrint('✅ FCM token deleted successfully');
|
|
|
|
return true;
|
|
} catch (e) {
|
|
debugPrint('❌ Error deleting FCM token: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 📡 Listen to token refresh events
|
|
void listenToTokenRefresh(Function(String) onTokenRefreshed) {
|
|
_messaging.onTokenRefresh.listen((newToken) {
|
|
debugPrint('🔔 FCM Token auto-refreshed by Firebase: $newToken');
|
|
onTokenRefreshed(newToken);
|
|
});
|
|
}
|
|
|
|
/// 🔄 Reset and get fresh token (comprehensive reset)
|
|
Future<String?> resetAndGetFreshToken() async {
|
|
try {
|
|
// Delete existing token
|
|
await deleteToken();
|
|
|
|
// Wait longer to ensure complete reset
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
|
|
// Regenerate
|
|
return await regenerateToken();
|
|
} catch (e) {
|
|
debugPrint('❌ Error in resetAndGetFreshToken: $e');
|
|
return null;
|
|
}
|
|
}
|
|
}
|