Data Layer Overview
Countly's data layer includes user properties, device data, and custom attributes that enhance segmentation and analysis.
User Properties
Setting User Properties
// Set user properties
Countly.user_details({
name: 'John Doe',
email: 'john@example.com',
organization: 'Acme Inc',
phone: '+1234567890',
picture: 'https://example.com/avatar.jpg',
gender: 'M',
byear: 1990,
custom: {
plan: 'premium',
signup_date: '2024-01-15',
credits: 100
}
});
Updating Properties
// Update specific properties
Countly.userData.set('plan', 'enterprise');
Countly.userData.set('last_login', new Date().toISOString());
Countly.userData.save();
Numeric Operations
// Increment
Countly.userData.increment('login_count');
Countly.userData.increment_by('credits', 50);
// Multiply
Countly.userData.multiply('score', 2);
// Max/Min
Countly.userData.max('high_score', 150);
Countly.userData.min('low_score', 10);
// Save changes
Countly.userData.save();
Array Operations
// Push to array
Countly.userData.push('tags', 'vip');
// Push unique
Countly.userData.push_unique('categories', 'premium');
// Pull from array
Countly.userData.pull('tags', 'trial');
Countly.userData.save();
Device Identification
Default Device ID
Countly generates a unique device ID automatically. Access it:
const deviceId = Countly.get_device_id();
Custom Device ID
Set your own device ID for cross-device tracking:
// Set during initialization
Countly.init({
app_key: 'YOUR_APP_KEY',
url: 'https://your-server.com',
device_id: 'custom_user_123'
});
Changing Device ID
// Merge with existing data
Countly.change_id('new_device_id', true);
// Without merge (new user)
Countly.change_id('new_device_id', false);
Custom Segments
Session Segments
Add segments to all events in a session:
Countly.init({
app_key: 'YOUR_APP_KEY',
url: 'https://your-server.com'
});
// Set session-wide segments
Countly.add_event({
key: 'session_start',
segmentation: {
app_version: '2.1.0',
ab_test_group: 'B',
user_tier: 'premium'
}
});
Event Segments
Include context with each event:
function trackWithContext(eventKey, eventData = {}) {
Countly.add_event({
key: eventKey,
count: eventData.count || 1,
sum: eventData.sum,
segmentation: {
...eventData.segmentation,
// Always include
platform: 'web',
locale: navigator.language,
viewport: `${window.innerWidth}x${window.innerHeight}`
}
});
}
Privacy Considerations
Consent Management
// Check if consent is required
Countly.init({
app_key: 'YOUR_APP_KEY',
url: 'https://your-server.com',
require_consent: true
});
// Grant consent
Countly.add_consent(['sessions', 'events', 'crashes']);
// Revoke consent
Countly.remove_consent(['sessions']);
Data Minimization
// Don't track PII
Countly.user_details({
custom: {
user_id: hashUserId(userId), // Hashed
plan: 'premium',
// Don't include: name, email, phone
}
});
Mobile SDKs
iOS User Properties
Countly.user().name = "John Doe"
Countly.user().email = "john@example.com"
Countly.user().custom = ["plan": "premium"]
Countly.user().save()
Android User Properties
Countly.sharedInstance().userProfile()
.setProperty("name", "John Doe")
.setProperty("plan", "premium")
.save()
Best Practices
- Use consistent property names
- Hash or anonymize PII
- Set properties after user authentication
- Update properties when values change
- Use numeric types for countable values