Flutter SDK - Setting Global Properties

Setting Global Properties

Define custom properties that automatically attach to every session and event sent from your app, enabling detailed data segmentation in reports.

Global properties let you track any user, app mode, or contextual information you need. For example, in a gaming app, create a "Level" property initialized to "0" that updates as users progress. All sessions and events include this property, allowing you to analyze sessions, event counts, and revenue broken down by user level.

Property Specifications

Limits and Persistence

Understand the constraints and persistence behavior of global properties before implementation.

  • Maximum Properties: Define up to 5 global properties per app installation.
  • Persistence: Properties persist between app launches with their most recent values until explicitly unset or the app is uninstalled.
  • Character Limit: Property names and values can be up to 200 characters long. Longer values are automatically truncated to 200 characters.
  • Data Availability: Global properties are accessible in user-level exports and postbacks. Contact your Singular customer success manager for updates on aggregate reporting support.

Setting Global Properties at Initialization

Configure Before SDK Initialization

Set global properties before SDK initialization using the globalProperties configuration property to ensure they're included in the initial session.

Since global properties persist between app launches, properties may already exist with different values. Use the overrideExisting parameter in the SingularGlobalProperty constructor to control whether the new value should override existing values.

Dart
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:singular_flutter_sdk/singular_global_property.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    initializeSDK();
  }

  void initializeSDK() {
    // Create configuration with global properties
    SingularConfig config = SingularConfig(
      'YOUR_SDK_KEY',
      'YOUR_SDK_SECRET'
    );

    // Set app-level global properties before initialization
    config.globalProperties = [
      SingularGlobalProperty('app_version', '1.2.3', true),
      SingularGlobalProperty('platform', 'flutter', true)
    ];

    // Initialize SDK with global properties
    Singular.start(config);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

Configuration Property:

List<SingularGlobalProperty> globalProperties

SingularGlobalProperty Constructor:

SingularGlobalProperty(String key, String value, bool overrideExisting)

Parameters:

  • key: Property name (max 200 characters)
  • value: Property value (max 200 characters)
  • overrideExisting: Whether to override an existing property with the same key

Managing Properties After Initialization

Set Global Property

Add or update a global property at any point during the app's runtime using setGlobalProperty().

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Set a global property after initialization
void updatePlayerLevel(int level) {
  Singular.setGlobalProperty(
    'player_level',
    level.toString(),
    true
  );

  print('Global property set: player_level = $level');
}

Method Signature:

static void setGlobalProperty(String key, String value, bool overrideExisting)

Important:

  • If 5 properties already exist and you attempt to add a new one with a different key, the SDK will not add it.
  • The overrideExisting parameter determines whether to replace existing property values.
  • Properties set during initialization or at runtime have the same persistence behavior.

Example: Update Property on User Action

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Example: Track user subscription tier
void handleSubscriptionChange(String tier) {
  // Update global property
  Singular.setGlobalProperty('subscription_tier', tier, true);

  // Track the subscription event
  Singular.eventWithArgs('subscription_changed', {
    'new_tier': tier,
    'timestamp': DateTime.now().toIso8601String()
  });

  print('Subscription tier updated: $tier');
}

Get Global Properties

Retrieve all currently set global properties and their values as a map.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Retrieve all global properties
Future<void> displayGlobalProperties() async {
  Map<String, String> properties = await Singular.getGlobalProperties();

  // Iterate through properties
  properties.forEach((key, value) {
    print('Property: $key = $value');
  });

  // Check if specific property exists
  if (properties.containsKey('player_level')) {
    print('Current player level: ${properties['player_level']}');
  }
}

Method Signature:

static Future<Map<String, String>> getGlobalProperties()

Returns: A Future that resolves to a Map<String, String> containing all global property key-value pairs.


Unset Global Property

Remove a specific global property by its key when you no longer need to track that dimension.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Remove a specific global property
Singular.unsetGlobalProperty('player_level');

Method Signature:

static void unsetGlobalProperty(String key)

Parameters:

  • key: The name of the property to remove

Example: Clear User Properties on Logout

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Clear user-specific properties on logout
void handleUserLogout() {
  // Remove user-specific properties
  Singular.unsetGlobalProperty('subscription_tier');
  Singular.unsetGlobalProperty('player_level');
  Singular.unsetGlobalProperty('user_segment');

  // Also clear custom user ID
  Singular.unsetCustomUserId();

  print('User properties cleared on logout');
}

Clear All Global Properties

Remove all global properties at once, typically when a user logs out or you need to reset all tracking properties.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Remove all global properties
Singular.clearGlobalProperties();

Method Signature:

static void clearGlobalProperties()

Best Practice: Use clearGlobalProperties() when a user logs out or when you need to reset all custom tracking properties to their default state. This is especially useful in multi-user scenarios where different users may log in on the same device.


Implementation Example

Complete Usage Pattern

Track app-level and user-specific properties throughout the application lifecycle with proper management during login and logout flows.

Dart
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:singular_flutter_sdk/singular_global_property.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    initializeSDK();
  }

  void initializeSDK() {
    // Set app-level global properties before initialization
    SingularConfig config = SingularConfig(
      'YOUR_SDK_KEY',
      'YOUR_SDK_SECRET'
    );

    config.globalProperties = [
      SingularGlobalProperty('app_version', '1.2.3', true),
      SingularGlobalProperty('platform', 'flutter', true)
    ];

    // Initialize SDK
    Singular.start(config);
  }

  // Set user-specific properties on login
  void handleUserLogin(String userId, String userTier) {
    // Set custom user ID
    Singular.setCustomUserId(userId);

    // Set user tier property
    Singular.setGlobalProperty('user_tier', userTier, true);

    // Set initial player level
    Singular.setGlobalProperty('player_level', '1', true);

    print('User properties set successfully');
  }

  // Update dynamic properties during gameplay
  void handleLevelUp(int newLevel) {
    // Update player level property
    Singular.setGlobalProperty('player_level', newLevel.toString(), true);

    // Track level up event
    Singular.eventWithArgs('level_up', {
      'new_level': newLevel.toString(),
      'timestamp': DateTime.now().millisecondsSinceEpoch.toString()
    });

    print('Level updated to $newLevel');
  }

  // Update subscription status
  void handleSubscriptionPurchase(String tier) {
    // Update subscription tier
    Singular.setGlobalProperty('subscription_tier', tier, true);

    // Track subscription event
    Singular.customRevenue('subscription_purchase', 'USD', 9.99);

    print('Subscription tier updated: $tier');
  }

  // Clear user-specific properties on logout
  void handleUserLogout() {
    // Remove user-specific properties
    Singular.unsetGlobalProperty('user_tier');
    Singular.unsetGlobalProperty('player_level');
    Singular.unsetGlobalProperty('subscription_tier');

    // Clear custom user ID
    Singular.unsetCustomUserId();

    print('User properties cleared on logout');
  }

  // Alternative: Clear all properties at once
  void handleCompleteReset() {
    // Remove all global properties
    Singular.clearGlobalProperties();

    // Clear custom user ID
    Singular.unsetCustomUserId();

    print('All properties and user ID cleared');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

Best Practice: Sync third-party analytics identifiers (e.g., Mixpanel distinct_id, Amplitude user_id) to Singular global properties for unified cross-platform tracking. Set user-specific identifiers on login and clear them with unsetGlobalProperty() on logout. App-level properties like app_version persist across sessions.


Common Use Cases

Gaming Apps

Track player progression, engagement level, and monetization tier to segment users and optimize campaigns.

  • player_level: Current level or stage in the game
  • vip_status: Premium membership tier (free, silver, gold)
  • last_purchase_date: Date of most recent in-app purchase
  • engagement_score: Calculated engagement metric

E-commerce Apps

Track customer segments, loyalty status, and shopping preferences to personalize marketing campaigns.

  • loyalty_tier: Customer loyalty program level
  • preferred_category: Most browsed product category
  • cart_status: Whether user has items in cart
  • lifetime_value_bucket: Categorized total spend (low, medium, high)

Content/Media Apps

Track content preferences, subscription status, and engagement patterns for content recommendations and retention.

  • subscription_type: Free, premium, or family plan
  • content_preference: Primary content category interest
  • download_quality: User's preferred streaming quality
  • watch_time_bucket: Categorized daily watch time

Property Limit Management: With a maximum of 5 global properties, prioritize the most valuable tracking dimensions for your analytics. If you reach the limit, consider removing less critical properties before adding new ones. Plan your property strategy carefully to maximize insights.