Appearance
Custom Events
Any event that could not be accommodated through predefined events, can be created through Custom Events.
Overview
Custom events allow you to track specific user interactions and business events that are unique to your application. These events provide detailed insights into user behavior and help you understand how users interact with your app's features.
Types of Events
Events in Upshot.ai are classified as timed and non-timed events.
Non-Timed Events
An event where the start time and end time are the same is a non-timed event.
Example: Say a button tap. It does not matter how long the button was pressed for. This is a non-timed event, where you are only interested in the fact that the button has been clicked.
dart
import 'package:flutter_upshot_plugin/flutter_upshot_plugin.dart';
// Create a non-timed event
Map<String, dynamic> eventData = {
"button_name": "login_button",
"screen_name": "login_screen"
};
FlutterUpshotPlugin.createCustomEvent("button_click", eventData, false);Timed Events
An event where the end time is different from the start time is a timed event.
Example: A game level takes 30 seconds to finish. So a "game level played" event starts at X and ends at Y. There's a time component associated with the event here, hence it is considered as a timed event.
dart
// Start a timed event
Map<String, dynamic> eventData = {
"level": 1,
"difficulty": "easy"
};
// This returns an eventId that you'll use to close the event
String eventId = await FlutterUpshotPlugin.createCustomEvent("game_level_start", eventData, true);Note
Events should be closed with the same eventId with which the event had started. Timed events have to be closed for the provided eventId.
Closing Timed Events
Simple Close Event
Event should be closed with the same eventId with which the event had started:
dart
// Close the event using the eventId
FlutterUpshotPlugin.closeEventForId(eventId);Set Data And Close Event
Any data needed is set while closing the event using the same eventId. Data set on the event will be available in the live events section:
dart
Map<String, dynamic> closeEventData = {
"score": 1500,
"completion_time": 45,
"success": true
};
FlutterUpshotPlugin.setValueAndClose(eventId, closeEventData);Common Use Cases
E-commerce Events
dart
// Track product view
Map<String, dynamic> productData = {
"product_id": "12345",
"product_name": "Wireless Headphones",
"category": "Electronics",
"price": 99.99,
"currency": "USD"
};
FlutterUpshotPlugin.createCustomEvent("product_view", productData, false);
// Track purchase
Map<String, dynamic> purchaseData = {
"order_id": "ORD-789",
"total_amount": 299.97,
"items_count": 3,
"payment_method": "credit_card"
};
FlutterUpshotPlugin.createCustomEvent("purchase", purchaseData, false);Media Events
dart
// Start video playback (timed event)
Map<String, dynamic> videoData = {
"video_id": "video_123",
"video_title": "Tutorial: Getting Started",
"duration": 300, // seconds
"quality": "1080p"
};
String videoEventId = await FlutterUpshotPlugin.createCustomEvent("video_start", videoData, true);
// Complete video playback
Map<String, dynamic> completionData = {
"watch_percentage": 85,
"watched_duration": 255,
"skipped": false
};
FlutterUpshotPlugin.setValueAndClose(videoEventId, completionData);Social Events
dart
// Share content
Map<String, dynamic> shareData = {
"content_type": "article",
"content_id": "article_456",
"share_platform": "twitter",
"content_title": "10 Tips for Better Sleep"
};
FlutterUpshotPlugin.createCustomEvent("content_share", shareData, false);
// Like/Reaction
Map<String, dynamic> reactionData = {
"content_id": "post_789",
"reaction_type": "like",
"user_id": "user_123"
};
FlutterUpshotPlugin.createCustomEvent("content_reaction", reactionData, false);Best Practices
- Consistent Naming: Use consistent naming conventions for events and properties
- Meaningful Names: Choose descriptive event names that clearly indicate what happened
- Property Validation: Validate event properties before sending to avoid errors
- Event Timing: Close timed events promptly to ensure accurate duration tracking
- Data Structure: Keep event data structure consistent across similar events
- Performance: Avoid creating too many events in rapid succession
Validation in Dashboard
You can check Events in Dashboard under Live Events section to validate that your custom events are being tracked correctly.
Troubleshooting
Common Issues
Timed Events Not Closing:
- Ensure you're using the same eventId to close the event
- Check that the eventId is not null or empty
- Verify the event was successfully created before attempting to close
Event Data Not Appearing:
- Validate that event data follows the correct format
- Check for special characters in property names
- Ensure event names don't exceed character limits
Events Not Dispatching:
- Verify SDK is properly initialized
- Check network connectivity
- Consider manually dispatching events if needed

