> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/development-guide/android/user-identifier.md).

# User Identifier & Properties

{% hint style="info" %}
User Identifier Management

User Identifiers are used to uniquely identify users. For information about the meaning and importance of User Identifiers, and how to choose them, refer to the [Manage User Identifiers](/en/getting-started/user-identifier.md) documentation.
{% endhint %}

{% hint style="warning" %}
For functions that change user information (`setUser`, `setUserId`, `setDeviceId`, `updateUserProperties`, `resetUser`, and so on), we recommend using the variants that take a callback.

The callback is invoked after the changed user information has been applied to the SDK.
{% endhint %}

## User Identifier

### Default Identifiers Provided by Hackle

The Android SDK includes functionality to manage the device's identifier. Therefore, users can be automatically identified without separately providing a User Identifier.

You can query the identifiers managed by the SDK as follows.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
// Get the device ID
val deviceId = hackleApp.deviceId

// Get the session ID
val sessionId = hackleApp.sessionId

// Get all user information
val user = hackleApp.user
```

{% endtab %}

{% tab title="Java" %}

```java
// Get the device ID
String deviceId = hackleApp.getDeviceId();

// Get the session ID
String sessionId = hackleApp.getSessionId();

// Get all user information
User user = hackleApp.getUser();
```

{% endtab %}
{% endtabs %}

#### Modify Device ID

You can inject a custom device ID instead of using the device ID provided by Hackle.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
// Change the device ID
hackleApp.setDeviceId("CUSTOM_DEVICE_ID") {
    // Applied
}

// Using the builder pattern
val user = User.builder()
    .deviceId("CUSTOM_DEVICE_ID") // Device ID
    .build()

hackleApp.setUser(user) {
    // Applied
}
```

{% endtab %}

{% tab title="Java" %}

```java
// Change the device ID
hackleApp.setDeviceId("CUSTOM_DEVICE_ID", () -> {
    // Applied
});
```

{% endtab %}
{% endtabs %}

#### Set User Identifier (User ID)

You can set the identifier for a logged-in user.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
// Add the logged-in user ID
hackleApp.setUserId("LOGIN_ID") {
    // Applied
}

// Using the builder pattern
val user = User.builder()
    .userId("LOGIN_ID") // User ID
    .build()

hackleApp.setUser(user) {
    // Applied
}
```

{% endtab %}

{% tab title="Java" %}

```java
// Add the logged-in user ID
hackleApp.setUserId("LOGIN_ID", () -> {
    // Applied
});
```

{% endtab %}
{% endtabs %}

### Additional Identifiers

You can add identifier types other than the default identifiers (deviceId, userId) as follows.

{% hint style="info" %}
Additional identifiers are not integrated with the [Hackle ID](/en/getting-started/user-identifier/hackle-id.md).
{% endhint %}

{% hint style="danger" %}
Calling `setUser` overwrites the current device's user information.

* If you are currently using userId A and call `setUser` without passing userId A, the userId changes from A to null.
* If you are currently using a custom deviceId and call `setUser` without passing the current deviceId, the custom deviceId reverts to the Hackle deviceId.
* If you use additional identifiers and do not pass them when calling `setUser`, the additional identifiers are reset.
* For properties, the cached properties on the device may be retained or reset in the following cases:
  * If the userId and deviceId are the same before and after `setUser`, cached properties are retained.
  * If the userId or deviceId changes before and after `setUser`, cached properties are deleted.
    {% endhint %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import io.hackle.sdk.common.User

val user = User.builder()
    .userId("143")                   // User ID (Hackle ID can be used)
    .deviceId("ae2182e0")            // Device ID (Hackle ID can be used)
    .identifier("myCustomId", "42")  // Custom ID
    .build()

hackleApp.setUser(user) {
    // Applied
}
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.common.User

User user = User.builder()
    .userId("143")                   // User ID (Hackle ID can be used)
    .deviceId("ae2182e0")            // Device ID (Hackle ID can be used)
    .identifier("myCustomId", "42")  // Custom ID
    .build();

hackleApp.setUser(user, () -> {
    // Applied
});
```

{% endtab %}
{% endtabs %}

## User Property

The Hackle SDK supports adding user properties.

* Properties must be sent as key-value pairs (Property Key and Property Value).
* A maximum of 128 properties can be added.

<table><thead><tr><th width="133.04296875">Category</th><th width="127.60546875">Type</th><th>Constraints</th></tr></thead><tbody><tr><td>Property Key</td><td><code>string</code></td><td><ul><li>Character limit is 128 characters.</li><li>Case-insensitive.</li><li>For example, AGE and age are recognized as the same Property Key.</li></ul></td></tr><tr><td>Property Value</td><td><code>boolean</code>, <code>string</code>, <code>number</code>, <code>array</code></td><td><ul><li>For string type, the character limit is 1024 characters.</li><li>String type is case-sensitive.</li><li>For example, APPLE and apple are recognized as different Property Values.</li><li>For number type, up to 15 integer digits and up to 6 decimal places are supported.</li></ul></td></tr></tbody></table>

### Add User Property

You can add a user property simply by adding it with `set` on a `PropertyOperations` object and then calling `updateUserProperties`.

{% hint style="warning" %}
The `setUserProperty` function is deprecated as of Android SDK 4.0.0. Use `updateUserProperties` instead.
{% endhint %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import io.hackle.sdk.common.PropertyOperations

// Set a property
val operations = PropertyOperations.builder()
    .set("gender", "female")
    .build()

hackleApp.updateUserProperties(operations) {
    // Applied
}
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.common.PropertyOperations;

// Set a property
PropertyOperations operations = PropertyOperations.builder()
    .set("gender", "female")
    .build();

hackleApp.updateUserProperties(operations, () -> {
    // Applied
});
```

{% endtab %}
{% endtabs %}

### Configure User Properties

You can add or remove user properties.

<table><thead><tr><th width="150">Supported Functions</th><th>Description</th></tr></thead><tbody><tr><td><code>set</code></td><td>Sets a User Property. If a Property Value already exists for the Property Key, it is overwritten.</td></tr><tr><td><code>setOnce</code></td><td><p>Sets a User Property value only once. If a property already exists for the Property Key, it is ignored.</p><p>For example, you can use this to set a user's registration date or initial sign-up location.</p></td></tr><tr><td><code>unset</code></td><td>Removes a User Property.</td></tr><tr><td><code>clearAll</code></td><td>Removes all User Properties.</td></tr></tbody></table>

Instantiate a `PropertyOperations` object with the user properties you want to configure. Then call `updateUserProperties` to update the user properties. You can configure multiple properties at once.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import io.hackle.sdk.common.PropertyOperations

// Set properties
val operations = PropertyOperations.builder()
    .set("age", 42)
    .set("grade", "GOLD")
    .setOnce("sign_up_date", "2020-07-03")
    .build()

hackleApp.updateUserProperties(operations) {
    // Applied
}

// Clear properties
val clearOperations = PropertyOperations.clearAll()

hackleApp.updateUserProperties(clearOperations) {
    // Applied
}
```

{% endtab %}

{% tab title="Java" %}

```java
import io.hackle.sdk.common.PropertyOperations;

// Set properties
PropertyOperations operations = PropertyOperations.builder()
    .set("age", 42)
    .set("grade", "GOLD")
    .setOnce("sign_up_date", "2020-07-03")
    .build();

hackleApp.updateUserProperties(operations, () -> {
    // Applied
});

// Clear properties
PropertyOperations clearOperations = PropertyOperations.clearAll();

hackleApp.updateUserProperties(clearOperations, () -> {
    // Applied
});
```

{% endtab %}
{% endtabs %}

## Reset User

You need to reset the previously configured information. When reset, all previously configured identifiers and properties are cleared.

{% hint style="danger" %}
Resetting the user also clears all user properties stored on the server. If you want to handle logout, use `hackleApp.setUserId(null)`.

Setting null to userId handles logout on the client side.
{% endhint %}

```kotlin
hackleApp.resetUser {
    // Applied
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/development-guide/android/user-identifier.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
