import 'dart:convert'; import 'package:googleapis_auth/auth_io.dart'; class AccessTokenManager { static final AccessTokenManager _instance = AccessTokenManager._internal(); late final String serviceAccountJsonKey; AccessToken? _accessToken; DateTime? _expiryDate; AccessTokenManager._internal(); factory AccessTokenManager(String jsonKey) { if (_instance._isServiceAccountKeyInitialized()) { // Prevent re-initialization return _instance; } _instance.serviceAccountJsonKey = jsonKey; return _instance; } bool _isServiceAccountKeyInitialized() { try { serviceAccountJsonKey; // Access to check if initialized return true; } catch (e) { return false; } } Future getAccessToken() async { if (_accessToken != null && DateTime.now().isBefore(_expiryDate!)) { return _accessToken!.data; } try { final serviceAccountCredentials = ServiceAccountCredentials.fromJson( json.decode(serviceAccountJsonKey)); final client = await clientViaServiceAccount( serviceAccountCredentials, ['https://www.googleapis.com/auth/firebase.messaging'], ); _accessToken = client.credentials.accessToken; _expiryDate = client.credentials.accessToken.expiry; client.close(); return _accessToken!.data; } catch (e) { throw Exception('Failed to obtain access token'); } } }