169 lines
5.8 KiB
Dart
169 lines
5.8 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:onesignal_flutter/onesignal_flutter.dart';
|
|
|
|
/// OneSignal service for managing push notifications and external user ID.
|
|
///
|
|
/// This service handles:
|
|
/// - Initializing OneSignal SDK
|
|
/// - Setting external user ID after login (using phone number)
|
|
/// - Restoring external user ID on app startup
|
|
/// - Clearing external user ID on logout
|
|
///
|
|
/// Usage:
|
|
/// ```dart
|
|
/// // Initialize in main.dart
|
|
/// await OneSignalService.init(appId: 'your-app-id');
|
|
///
|
|
/// // After successful login
|
|
/// await OneSignalService.login(phoneNumber);
|
|
///
|
|
/// // On logout
|
|
/// await OneSignalService.logout();
|
|
/// ```
|
|
class OneSignalService {
|
|
OneSignalService._();
|
|
|
|
/// OneSignal App ID - Replace with your actual App ID from OneSignal dashboard
|
|
static const String _defaultAppId = '778ca22d-c719-4ec8-86cb-a6b911166066';
|
|
|
|
/// Initialize OneSignal SDK
|
|
///
|
|
/// Must be called before using any other OneSignal methods.
|
|
/// Sets up push subscription observers and requests notification permission.
|
|
///
|
|
/// [appId] - Optional App ID override (uses default if not provided)
|
|
/// [requestPermission] - Whether to request notification permission (default: true)
|
|
static Future<void> init({
|
|
String? appId,
|
|
bool requestPermission = true,
|
|
}) async {
|
|
try {
|
|
// Set debug log level (verbose in debug, none in release)
|
|
OneSignal.Debug.setLogLevel(kDebugMode ? OSLogLevel.verbose : OSLogLevel.none);
|
|
|
|
// Initialize with App ID
|
|
OneSignal.initialize(appId ?? _defaultAppId);
|
|
debugPrint('🔔 OneSignal initialized');
|
|
|
|
// Add push subscription observer to track subscription state changes
|
|
OneSignal.User.pushSubscription.addObserver((state) {
|
|
debugPrint('🔔 Push subscription state changed:');
|
|
debugPrint(' Previous - optedIn: ${state.previous.optedIn}, id: ${state.previous.id}');
|
|
debugPrint(' Current - optedIn: ${state.current.optedIn}, id: ${state.current.id}');
|
|
debugPrint(' Subscription ID: ${state.current.id}');
|
|
debugPrint(' Push Token: ${state.current.token}');
|
|
|
|
if (state.current.id != null) {
|
|
debugPrint('🔔 ✅ Device successfully subscribed!');
|
|
}
|
|
});
|
|
|
|
// Add notification permission observer
|
|
OneSignal.Notifications.addPermissionObserver((isGranted) {
|
|
debugPrint('🔔 Notification permission changed: $isGranted');
|
|
});
|
|
|
|
// Request permission if enabled
|
|
if (requestPermission) {
|
|
final accepted = await OneSignal.Notifications.requestPermission(true);
|
|
debugPrint('🔔 Permission request result: $accepted');
|
|
}
|
|
|
|
// Give OneSignal SDK time to complete initialization and server registration
|
|
await Future<void>.delayed(const Duration(seconds: 2));
|
|
|
|
// Log current subscription status
|
|
_logSubscriptionStatus();
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to initialize - $e');
|
|
}
|
|
}
|
|
|
|
/// Log current subscription status for debugging
|
|
static void _logSubscriptionStatus() {
|
|
final optedIn = OneSignal.User.pushSubscription.optedIn;
|
|
final id = OneSignal.User.pushSubscription.id;
|
|
final token = OneSignal.User.pushSubscription.token;
|
|
|
|
debugPrint('🔔 Current subscription status:');
|
|
debugPrint(' Opted In: $optedIn');
|
|
debugPrint(' Subscription ID: $id');
|
|
debugPrint(' Push Token: $token');
|
|
|
|
if (id == null) {
|
|
debugPrint('🔔 ⚠️ Subscription ID is null - check device connectivity and OneSignal app ID');
|
|
}
|
|
}
|
|
|
|
/// Login user to OneSignal by setting external user ID.
|
|
///
|
|
/// This associates the device with the user's phone number,
|
|
/// allowing targeted push notifications to specific users.
|
|
///
|
|
/// [phoneNumber] - The user's phone number (used as external ID)
|
|
static Future<void> login(String phoneNumber) async {
|
|
try {
|
|
// Set external user ID for targeting
|
|
await OneSignal.login(phoneNumber);
|
|
debugPrint('🔔 OneSignal: login - external_id set to $phoneNumber');
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to set external user ID - $e');
|
|
}
|
|
}
|
|
|
|
/// Logout user from OneSignal by removing external user ID.
|
|
///
|
|
/// This disassociates the device from the user,
|
|
/// so notifications won't be sent to this specific user anymore.
|
|
static Future<void> logout() async {
|
|
try {
|
|
await OneSignal.logout();
|
|
debugPrint('🔔 OneSignal: logout - external_id cleared');
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to clear external user ID - $e');
|
|
}
|
|
}
|
|
|
|
/// Add a tag to the user for segmentation.
|
|
///
|
|
/// Tags can be used to segment users for targeted notifications.
|
|
/// Example: tier = "diamond", role = "contractor"
|
|
static Future<void> setTag(String key, String value) async {
|
|
try {
|
|
await OneSignal.User.addTagWithKey(key, value);
|
|
debugPrint('🔔 OneSignal: tag set - $key: $value');
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to set tag - $e');
|
|
}
|
|
}
|
|
|
|
/// Add multiple tags at once.
|
|
static Future<void> setTags(Map<String, String> tags) async {
|
|
try {
|
|
await OneSignal.User.addTags(tags);
|
|
debugPrint('🔔 OneSignal: tags set - $tags');
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to set tags - $e');
|
|
}
|
|
}
|
|
|
|
/// Remove a tag from the user.
|
|
static Future<void> removeTag(String key) async {
|
|
try {
|
|
await OneSignal.User.removeTag(key);
|
|
debugPrint('🔔 OneSignal: tag removed - $key');
|
|
} catch (e) {
|
|
debugPrint('🔔 OneSignal error: Failed to remove tag - $e');
|
|
}
|
|
}
|
|
|
|
/// Get the OneSignal subscription ID (player ID).
|
|
///
|
|
/// This is the device-specific ID used by OneSignal.
|
|
static String? get subscriptionId => OneSignal.User.pushSubscription.id;
|
|
|
|
/// Check if push notifications are enabled.
|
|
static bool get isPushEnabled =>
|
|
OneSignal.User.pushSubscription.optedIn ?? false;
|
|
}
|