User Properties

Set custom user properties

User properties are attributes you can set on a user level. You can send user properties to third-party platforms and use them in Qonversion for customer segmentation and analytics.
Here is an example of user properties:

968

User Properties

Usage

There are two types of user properties: Qonversion-defined and custom user properties.

Defined User Properties

We defined some common case properties and provided API for adding them:

Qonversion.shared().setUserProperty(.email, value: "[email protected]")
[[Qonversion sharedInstance] setUserProperty:QONUserPropertyKeyEmail value:@"[email protected]"];
Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.Email, "[email protected]");
Qonversion.shared.setUserProperty(QUserPropertyKey.Email, "[email protected]")
Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.email, '[email protected]');
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.EMAIL, '[email protected]');
Qonversion.GetSharedInstance().SetUserProperty(UserPropertyKey.Email, "[email protected]");
Qonversion.getSharedInstance().setUserProperty(Qonversion.UserPropertyKey.EMAIL, '[email protected]');
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.EMAIL, '[email protected]');

The full list of the defined properties is provided below:

NameKeyDescription
Email\_q_emailUser Email. It can be used for cross-platform authorization and integrations with Qonversion.
Name\_q_nameUser Name
KochavaDeviceId\_q_kochava_device_idKochava Unique Device ID
AppsFlyerUserId\_q_appsflyer_user_idCustomer user ID. It can be used to cross-reference your in-house data with AppsFlyer attribution data.
AdjustAdId\_q_adjust_adidAdjust Advertising ID
CustomUserId\_q_custom_user_idYour Internal User ID. Use User ID for third-party Integrations to attribute events to existing users in other platforms.
FacebookAttribution\_q_fb_attributionMobile Cookie from the user's device
FirebaseAppInstanceId\_q_firebase_instance_idThe identifier for a Firebase app
AppSetId\_q_app_set_idUnique user identifier for all the developer's applications on Android
AdvertisingId\_q_advertising_idUnique user identifier assigned to a mobile device on iOS
PushWooshUserId\_q_pushwoosh_user_idUnique user identifier assigned to PooshWosh. Used for PooshWosh integration.
PushWooshHwId\_q_pushwoosh_hwidHardware identifier generated by PooshWosh. Used for PooshWosh integration.
AppMetricaDeviceId\_q_appmetrica_device_idDevice identifier from AppMetrica. Used for AppMetrica integration.
AppMetricalProfileId\_q_appmetrica_user_profile_idUser profile identifier from AppMetrica. Used for AppMetrica integration.

Custom User Properties

Additionally, you can add custom user property. Qonversion can send them to third-party integrations as well. For example, you can add user details and use that data to send personalized emails or push notifications via Mailchimp and OneSignal integrations.

Qonversion.shared().setCustomUserProperty("liked-app", value: "yes")
[[Qonversion sharedInstance] setCustomUserProperty: @"liked-app" value: @"yes"];
Qonversion.getSharedInstance().setCustomUserProperty("liked-app", "yes");
Qonversion.shared.setCustomUserProperty("liked-app", "yes")
Qonversion.getSharedInstance().setCustomUserProperty('liked-app', 'yes');
Qonversion.getSharedInstance().setCustomUserProperty('liked-app', 'yes');
Qonversion.GetSharedInstance().SetCustomUserProperty("liked-app", "yes");
Qonversion.getSharedInstance().setCustomUserProperty('liked-app', 'yes');
Qonversion.getSharedInstance().setCustomUserProperty('liked-app', 'yes');

You can use letters A-Za-z, numbers, and the following symbols _.:- as a property key.

📘

Property setting order

To successfully set either Defined or Custom User Properties, launch Qonversion SDK first. Learn more.

Get User Properties

You can get user properties set for a current user as follows:

Qonversion.shared().userProperties({ userProperties, error in
  if let error = error {
    // Handle error
    return
  }
  
  userProperties?.properties.forEach({ userProperty in
    print("User property: ", "key: ", userProperty.key, ", value: ", userProperty.value)
  })
});
[[Qonversion sharedInstance] userProperties:^(QONUserProperties * _Nullable userProperties, NSError * _Nullable error) {
  if (error) {
    // Handle error
    return;
  }

  [userProperties.properties enumerateObjectsUsingBlock:^(QONUserProperty * _Nonnull userProperty, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"User property: key: %@, value: %@", userProperty.key, userProperty.value);
  }];
}];
Qonversion.getSharedInstance().userProperties(new QonversionUserPropertiesCallback() {
    @Override
    public void onSuccess(@NonNull QUserProperties userProperties) {
        for (QUserProperty property : userProperties.getProperties()) {
            Log.d("User property", "Key: " + property.getKey() +
                    ", value: " + property.getValue());
        }
    }

    @Override
    public void onError(@NonNull QonversionError error) {
        // handle error here
    }
});
Qonversion.shared.userProperties(object : QonversionUserPropertiesCallback {
  override fun onSuccess(userProperties: QUserProperties) {
    userProperties.properties.forEach { 
      Log.d("User property", "key: ${it.key}, value: ${it.value}")
    }
  }

  override fun onError(error: QonversionError) {
    // handle error here
  }
})
try {
  QUserProperties userProperties = await Qonversion.getSharedInstance().userProperties();
  userProperties.properties.forEach((userProperty) {
    print('User property - key: ' + userProperty.key + ', value: ' + userProperty.value);
  });
} catch (e) {
  // handle error here
}
try {
  const userProperties = await Qonversion.getSharedInstance().userProperties();
  userProperties.properties.forEach(userProperty => {
    console.log('User property - key:' + userProperty.key + ', value: ' + userProperty.value);
  });
} catch (e) {
  // handle error here
}
Qonversion.GetSharedInstance().UserProperties((userProperties, error) =>
{
    if (error != null)
    {
        // Handle the error  
        Debug.LogError("Error" + error);   
    }
    else
    {
        userProperties.Properties.ForEach(userProperty => {
            Debug.Log("User property - key: " + userProperty.Key + ", value: " + userProperty.Value);
        });
    }
});
try {
  const userProperties = await Qonversion.getSharedInstance().userProperties();
  userProperties.properties.forEach(userProperty => {
    console.log('User property - key:' + userProperty.key + ', value: ' + userProperty.value);
  });
} catch (e) {
  // handle error here
}
try {
  const userProperties = await Qonversion.getSharedInstance().userProperties();
  userProperties.properties.forEach(userProperty => {
    console.log('User property - key:' + userProperty.key + ', value: ' + userProperty.value);
  });
} catch (e) {
  // handle error here
}

The object returned by userProperties method contains several utility fields and methods:

Qonversion.shared().userProperties({ userProperties, error in
  ...
  // List of all user properties
  let allProperties = userProperties?.properties

  // Subset of all user properties, which were set using Qonversion-defined keys                                  
  let definedProperties = userProperties?.definedProperties
                                    
  // Subset of all user properties, which were set using custom keys
  let customProperties = userProperties?.customProperties
                                    
  // A flattened version of all user properties as a key-value map
  let flatPropertiesMap = userProperties?.flatPropertiesMap
                                    
  // A flattened version of defined user properties as a key-value map
  let flatDefinedPropertiesMap = userProperties?.flatDefinedPropertiesMap
                                    
  // A flattened version of custom user properties as a key-value map
  let flatCustomPropertiesMap = userProperties?.flatCustomPropertiesMap
                                     
  // Searches for a property with the given property key in all properties list
  let customProperty = userProperties?.property(for: "customKey")

  // Searches for a property with the given Qonversion-defined property key in the defined properties list.
  let emailProperty = userProperties?.definedProperty(for: .email)
});
[[Qonversion sharedInstance] userProperties:^(QONUserProperties * _Nullable userProperties, NSError * _Nullable error) {
  ...
  // List of all user properties
  NSMutableArray<QONUserProperty *> *allProperties = userProperties.properties;
  
  // Subset of all user properties, which were set using Qonversion-defined keys
  NSMutableArray<QONUserProperty *> *definedProperties = userProperties.definedProperties;
  
  // Subset of all user properties, which were set using custom keys
  NSMutableArray<QONUserProperty *> *customProperties = userProperties.customProperties;
  
  // A flattened version of all user properties as a key-value map
  NSMutableDictionary<NSString *, NSString *> *flatPropertiesMap = userProperties.flatPropertiesMap;
  
  // A flattened version of defined user properties as a key-value map
  NSMutableDictionary<NSNumber *, NSString *> *flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap;
  
  // A flattened version of custom user properties as a key-value map
  NSMutableDictionary<NSString *, NSString *> *flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap;
  
  // Searches for a property with the given property key in all properties list
  QONUserProperty *customProperty = [userProperties propertyForKey:@"customKey"];
  
  // Searches for a property with the given Qonversion-defined property key in the defined properties list.
  QONUserProperty *emailProperty = [userProperties definedPropertyForKey:QONUserPropertyKeyEmail];
}];
Qonversion.getSharedInstance().userProperties(new QonversionUserPropertiesCallback() {
    @Override
    public void onSuccess(@NonNull QUserProperties userProperties) {
			  // List of all user properties
        List<QUserProperty> allProperties = userProperties.getProperties();
  
  		  // Subset of all user properties, which were set using Qonversion-defined keys
        List<QUserProperty> definedProperties = userProperties.getDefinedProperties();
  
  		  // Subset of all user properties, which were set using custom keys
        List<QUserProperty> customProperties = userProperties.getCustomProperties();
  
  		  // A flattened version of all user properties as a key-value map
        Map<String, String> flatPropertiesMap = userProperties.getFlatPropertiesMap();
  
  		  // A flattened version of defined user properties as a key-value map
        Map<QUserPropertyKey, String> flatDefinedPropertiesMap = userProperties.getFlatDefinedPropertiesMap();
  
  		  // A flattened version of custom user properties as a key-value map
        Map<String, String> flatCustomPropertiesMap = userProperties.getFlatCustomPropertiesMap();
  
  		  // Searches for a property with the given property key in all properties list
        QUserProperty customProperty = userProperties.getProperty("customKey");
  
  		  // Searches for a property with the given Qonversion-defined property key in the defined properties list.
        QUserProperty emailProperty = userProperties.getDefinedProperty(QUserPropertyKey.Email);
    }

    ...
});
Qonversion.shared.userProperties(object : QonversionUserPropertiesCallback {
  override fun onSuccess(userProperties: QUserProperties) {
  	// List of all user properties
    val allProperties = userProperties.properties
  
  	// Subset of all user properties, which were set using Qonversion-defined keys
    val definedProperties = userProperties.definedProperties
  
  	// Subset of all user properties, which were set using custom keys
    val customProperties = userProperties.customProperties
  
  	// A flattened version of all user properties as a key-value map
    val flatPropertiesMap = userProperties.flatPropertiesMap
  
  	// A flattened version of defined user properties as a key-value map
    val flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap
  
  	// A flattened version of custom user properties as a key-value map
    val flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap
  
  	// Searches for a property with the given property key in all properties list
    val customProperty = userProperties.getProperty("customKey")
  
  	// Searches for a property with the given Qonversion-defined property key in the defined properties list.
    val emailProperty = userProperties.getDefinedProperty(QUserPropertyKey.Email)
  }
  ...
})
var userProperties = await Qonversion.getSharedInstance().userProperties();

// List of all user properties
var allProperties = userProperties.properties;

// Subset of all user properties, which were set using Qonversion-defined keys
var definedProperties = userProperties.definedProperties;

// Subset of all user properties, which were set using custom keys
var customProperties = userProperties.customProperties;

// A flattened version of all user properties as a key-value map
var flatPropertiesMap = userProperties.flatPropertiesMap;

// A flattened version of defined user properties as a key-value map
var flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap;

// A flattened version of custom user properties as a key-value map
var flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap;
                                     
// Searches for a property with the given property key in all properties list
var customProperty = userProperties.getProperty("customKey");
 
// Searches for a property with the given Qonversion-defined property key in the defined properties list.
var emailProperty = userProperties.getDefinedProperty(QUserPropertyKey.email);
const userProperties = await Qonversion.getSharedInstance().userProperties();

// List of all user properties
const allProperties = userProperties.properties;

// Subset of all user properties, which were set using Qonversion-defined keys
const definedProperties = userProperties.definedProperties;

// Subset of all user properties, which were set using custom keys
const customProperties = userProperties.customProperties;

// A flattened version of all user properties as a key-value map
const flatPropertiesMap = userProperties.flatPropertiesMap;

// A flattened version of defined user properties as a key-value map
const flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap;

// A flattened version of custom user properties as a key-value map
const flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap;
                                     
// Searches for a property with the given property key in all properties list
const customProperty = userProperties.getProperty('customKey');
 
// Searches for a property with the given Qonversion-defined property key in the defined properties list.
const emailProperty = userProperties.getDefinedProperty(UserPropertyKey.EMAIL);
Qonversion.GetSharedInstance().UserProperties((userProperties, error) =>
{
    ...
		// List of all user properties
    List<UserProperty> allProperties = userProperties.Properties;

		// Subset of all user properties, which were set using Qonversion-defined keys
    List<UserProperty> definedProperties = userProperties.DefinedProperties;

		// Subset of all user properties, which were set using custom keys
    List<UserProperty> customProperties = userProperties.CustomProperties;

		// A flattened version of all user properties as a key-value map
    Dictionary<string, string> flatPropertiesMap = userProperties.FlatPropertiesMap;

		// A flattened version of defined user properties as a key-value map
    Dictionary<UserPropertyKey, string> flatDefinedPropertiesMap = userProperties.FlatDefinedPropertiesMap;

		// A flattened version of custom user properties as a key-value map
    Dictionary<string, string> flatCustomPropertiesMap = userProperties.FlatCustomPropertiesMap;
                                     
		// Searches for a property with the given property key in all properties list
    UserProperty customProperty = userProperties.GetProperty("customKey");
 
		// Searches for a property with the given Qonversion-defined property key in the defined properties list.
    UserProperty emailProperty = userProperties.GetDefinedProperty(UserPropertyKey.Email);
});
const userProperties = await Qonversion.getSharedInstance().userProperties();

// List of all user properties
const allProperties = userProperties.properties;

// Subset of all user properties, which were set using Qonversion-defined keys
const definedProperties = userProperties.definedProperties;

// Subset of all user properties, which were set using custom keys
const customProperties = userProperties.customProperties;

// A flattened version of all user properties as a key-value map
const flatPropertiesMap = userProperties.flatPropertiesMap;

// A flattened version of defined user properties as a key-value map
const flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap;

// A flattened version of custom user properties as a key-value map
const flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap;
                                     
// Searches for a property with the given property key in all properties list
const customProperty = userProperties.getProperty('customKey');
 
// Searches for a property with the given Qonversion-defined property key in the defined properties list.
const emailProperty = userProperties.getDefinedProperty(Qonversion.UserPropertyKey.EMAIL);
const userProperties = await Qonversion.getSharedInstance().userProperties();

// List of all user properties
const allProperties = userProperties.properties;

// Subset of all user properties, which were set using Qonversion-defined keys
const definedProperties = userProperties.definedProperties;

// Subset of all user properties, which were set using custom keys
const customProperties = userProperties.customProperties;

// A flattened version of all user properties as a key-value map
const flatPropertiesMap = userProperties.flatPropertiesMap;

// A flattened version of defined user properties as a key-value map
const flatDefinedPropertiesMap = userProperties.flatDefinedPropertiesMap;

// A flattened version of custom user properties as a key-value map
const flatCustomPropertiesMap = userProperties.flatCustomPropertiesMap;
                                     
// Searches for a property with the given property key in all properties list
const customProperty = userProperties.getProperty('customKey');
 
// Searches for a property with the given Qonversion-defined property key in the defined properties list.
const emailProperty = userProperties.getDefinedProperty(UserPropertyKey.EMAIL);

(Optional) Set User ID

If you want to implement cross-platform (Android, IOS, and Web) user entitlement management, please, follow the User Identity guide.

To match Qonversion revenue events to users in third-party tools, you need to set the identical user IDs in all of them:

Qonversion.shared().setUserProperty(.userID, value: "yourSideUserId")
[[Qonversion sharedInstance] setUserProperty:QNUserPropertyKeyUserID value:@"yourSideUserId"];
Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.CustomUserId, "yourSideUserID");
Qonversion.shared.setUserProperty(QUserPropertyKey.CustomUserId, "yourSideUserID")
Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.customUserId, 'yourSideUserId');
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.CUSTOM_USER_ID, 'yourSideUserId');
Qonversion.GetSharedInstance().SetUserProperty(UserPropertyKey.CustomUserId, "yourSideUserId");
Qonversion.getSharedInstance().setUserProperty(Qonversion.UserPropertyKey.CUSTOM_USER_ID, 'yourSideUserId');
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.CUSTOM_USER_ID, 'yourSideUserId');

The user ID improves the quality of events matching to the platforms where event attribution is not exclusively based on IDFA or GAID.

(Optional) Set IDFA (Identifier for Advertisers, iOS 14.5+ only)

On iOS 14.5+, after requesting the app tracking permission using ATT, you need to notify Qonversion if tracking is allowed and IDFA is available. This will help to have precise attribution in Adjust, AppsFlyer, Singular and other Qonversion integrations.

ATTrackingManager.requestTrackingAuthorization { status in
    switch status {
    case .authorized:
        Qonversion.shared().collectAdvertisingId()
      
    // handle other states below
    }
}
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    switch (status) {
        case ATTrackingManagerAuthorizationStatusAuthorized:
            [[Qonversion sharedInstance] collectAdvertisingId];
            break;
        
        // handle other states if needed
        
        default:
          break;
    }
}];
Qonversion.getSharedInstance().collectAdvertisingId();
Qonversion.getSharedInstance().collectAdvertisingId();
Qonversion.GetSharedInstance().CollectAdvertisingId();
Qonversion.getSharedInstance().collectAdvertisingId();
Qonversion.getSharedInstance().collectAdvertisingId();

(Optional) Set ASID (App set ID, Android 12+ only)

On Android 12+, you can provide an App set ID to have it used in Qonversion integrations.

Add com.google.android.gms:play-services-appset as the dependency to your project and write the following code.

final AppSetIdClient client = AppSet.getClient(context);
final Task<AppSetIdInfo> task = client.getAppSetIdInfo();
task.addOnSuccessListener(info -> {
    final String id = info.getId();
    Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.AppSetId, id);
});
val client = AppSet.getClient(requireContext())
client.appSetIdInfo.addOnSuccessListener { info: AppSetIdInfo ->
    Qonversion.shared.setUserProperty(QUserPropertyKey.AppSetId, info.id)
}
Qonversion.getSharedInstance().setUserProperty(QUserPropertyKey.appSetId, appSetId);
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.APP_SET_ID, appSetId);
Qonversion.GetSharedInstance().SetUserProperty(UserPropertyKey.AppSetId, appSetId);
Qonversion.getSharedInstance().setUserProperty(Qonversion.UserPropertyKey.APP_SET_ID, appSetId);
Qonversion.getSharedInstance().setUserProperty(UserPropertyKey.APP_SET_ID, appSetId);