Flutter User Behaviour

Tracking User Behaviour

Track Custom Events

Create a RetenoCustomEvent and pass it to the Reteno instance:

import 'package:reteno_plugin/reteno.dart';

final event = RetenoCustomEvent(
  eventTypeKey: 'product_added_to_favorites',
  dateOccurred: DateTime.now(),
  parameters: [
    RetenoCustomEventParameter('product_id', 'PRODUCT_ID'),
    RetenoCustomEventParameter('source', 'product_page'),
  ],
  forcePush: false,
);

await Reteno().logEvent(event: event);

The event fields are:

FieldTypeDescription
eventTypeKeyStringRequired. Event type key agreed with the marketing team
dateOccurredDateTimeRequired. Event time, serialized as UTC ISO 8601
parametersList<RetenoCustomEventParameter>Required. Pass an empty list when the event has no parameters
forcePushboolOptional, defaults to false. Sends the event immediately on iOS instead of waiting for the next batch; ignored on Android

RetenoCustomEventParameter takes two positional arguments: String name and String? value. Use non-null values: Android drops a null value, iOS sends it as an empty string.

The returned Future<bool> resolves after the native call is dispatched, not after the backend ingests the event.

Log Parameters from a Map

For string-valued parameters, logEventJson() provides a shorter equivalent:

await Reteno().logEventJson(
  eventTypeKey: 'product_added_to_favorites',
  jsonParameters: {
    'product_id': 'PRODUCT_ID',
    'source': 'product_page',
  },
  dateOccurred: DateTime.now(),
  forcePush: false,
);

eventTypeKey and jsonParameters are required; map values cannot be null. dateOccurred defaults to DateTime.now() and forcePush defaults to false.

iOS timestamp limitation

The iOS bridge does not accept timestamps with fractional seconds, which DateTime.now() produces, and silently substitutes the current native time. Android preserves dateOccurred. Do not rely on a historical custom-event timestamp on iOS.