callSecureOps static method

Future<Map<String, dynamic>> callSecureOps(
  1. Map<String, dynamic> data
)

Calls secureOps. On web, uses secureOpsWeb (HTTP with CORS). On mobile, uses the callable secureOps via Firebase SDK.

Implementation

static Future<Map<String, dynamic>> callSecureOps(Map<String, dynamic> data) async {
  if (kIsWeb) {
    final user = FirebaseAuth.instance.currentUser;
    final isPublicAction = data['action'] == 'getConfig';

    if (user == null && !isPublicAction) {
      throw Exception('Authentication required — user not logged in');
    }

    final url = Uri.parse(_getSecureOpsWebUrl());

    final token = user != null ? await user.getIdToken() : null;
    final headers = <String, String>{
      'Content-Type': 'application/json',
      if (token != null) 'Authorization': 'Bearer $token',
    };

    final response = await http.post(
      url,
      headers: headers,
      body: jsonEncode({'data': data}),
    );

    if (response.statusCode != 200) {
      throw Exception('secureOpsWeb HTTP ${response.statusCode}: ${response.body}');
    }

    final body = jsonDecode(response.body);
    if (body is Map<String, dynamic>) {
      if (body['error'] != null) {
        final err = body['error'];
        throw Exception(err is Map ? (err['message'] ?? 'Unknown error') : err.toString());
      }
      // onCall wraps in 'result', HTTP returns directly
      if (body.containsKey('result') && body['result'] is Map) {
        return body['result'] as Map<String, dynamic>;
      }
      return body;
    }
    return {};
  }

  // Mobile: use Firebase SDK callable
  final callable = FirebaseFunctions.instance.httpsCallable('secureOps');
  final result = await callable.call<Map<String, dynamic>>(data);
  return result.data;
}