push method

Future<RelevaResponse> push(
  1. PushRequest request
)

Implementation

Future<RelevaResponse> push(PushRequest request) async {
  if (!_config.enableTracking) {
    // Return empty response if tracking is disabled
    return RelevaResponse(recommenders: [], banners: []);
  }
  final storage = HiveStorageService.instance;
  final sessionId = await _getSessionId();
  final wishlistProducts = await storage.getWishlistData();

  // Use cart from request if explicitly set (e.g., for checkout success),
  // otherwise load from storage for regular screen views
  final String? cartToSend;
  if (request.cart != null) {
    // Cart explicitly provided in request (checkout success case)
    cartToSend = jsonEncode(request.cart!.toMap());
  } else {
    // Load from storage for regular tracking
    cartToSend = await storage.getCartData();
  }

  final deviceId = await storage.getDeviceId();
  if (deviceId == null) {
    throw Exception(
      'Please provide deviceId using client.setDeviceId() before using the client!',
    );
  }

  // Load merge profile IDs from storage so all instances share the same merge state
  final mergeProfileIds = await storage.getMergeProfileIds() ?? [];
  if (mergeProfileIds.isNotEmpty) {
    debugPrint('Releva: Sending merge profile IDs to API: $mergeProfileIds');
  }

  Map<String, dynamic> context = request.toMap();

  context.addAll({
    'deviceId': deviceId,
    'deviceIdChanged': _deviceIdChanged,
    'sessionId': sessionId,
    'profile': {'id': await storage.getProfileId()},
    'profileChanged': _profileChanged,
    'cart': cartToSend == null ? null : jsonDecode(cartToSend),
    'cartChanged': _cartChanged,
    'wishlist': {
      'products': wishlistProducts == null
          ? []
          : wishlistProducts.map((p) => jsonDecode(p)).toList(),
    },
    'wishlistChanged': _wishlistChanged,
    'mergeProfileIds': mergeProfileIds,
  });

  try {
    final response = await http.post(
      Uri.parse('${_getEndpoint()}/api/v0/push'),
      headers: {
        'content-type': 'application/json',
        'authorization': 'Bearer $_accessToken',
      },
      body: jsonEncode({
        'context': context,
        'options': {
          'client': {
            'vendor': 'Releva',
            'platform': 'flutter',
            'version': version,
          },
        },
      }),
    );

    if (response.statusCode != 200) {
      throw Exception(
        'Backend API error: ${response.statusCode} - ${response.body}',
      );
    }

    _cartChanged = false;
    _wishlistChanged = false;
    _profileChanged = false;
    _deviceIdChanged = false;
    // Clear merge profile IDs from storage after successful push
    await storage.clearMergeProfileIds();

    final responseMap =
        jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
    return RelevaResponse.fromMap(responseMap);
  } catch (e) {
    rethrow;
  }
}