# User Identifier & Properties

{% hint style="info" %}
Managing User Identifiers

User identifiers are used to uniquely identify users. For details on the meaning and importance of user identifiers and guidelines for choosing them, refer to the [Managing User Identifiers](/en/getting-started/user-identifier.md) documentation.
{% endhint %}

## User Identifier

### Default Identifiers Provided by Hackle

The JavaScript SDK includes functionality for managing device identifiers. Therefore, users can be identified automatically without providing a separate user identifier.

You can retrieve the identifier managed by the SDK as follows.

```javascript
// 사용자 정보 가지고 오기
const user = await hackleClient.getUser();

// 디바이스 식별자 가져오기
const deviceId = getDeviceId();
```

#### Modifying Device ID

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

```javascript
// 디바이스 식별자 변경
await hackleClient.setDeviceId("CUSTOM_DEVICE_ID");
```

#### Setting User Identifier (User ID)

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

```javascript
// 로그인 한 사용자 식별자 추가
await hackleClient.setUserId("LOGIN_ID");
```

### Additional Identifiers

To add identifier types other than the default identifiers (deviceId, userId), configure them as shown below.

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

{% hint style="danger" %}
Using `setUser` overwrites the user information on the current device.

* If you are currently using user ID A and call `setUser` without passing user ID 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 are using additional identifiers and call `setUser` without passing them, the additional identifiers are reset.
* For properties, the cached properties on the device may be retained or cleared based on the following cases:
  * If userId and deviceId are the same before and after `setUser`, cached properties are retained.
  * If userId or deviceId changes before and after `setUser`, cached properties are deleted.
    {% endhint %}

```javascript
const prevUser = await hackleClient.getUser();

const user = {
  ...prevUser, // 이전 유저 정보
  userId: "143", // 사용자 ID (핵클 통합 식별자 사용가능)
  deviceId: "ae2182e0", // 디바이스 ID (핵클 통합 식별자 사용가능)
  identifiers: {
    myCustomId: "42" // Custom ID
  }
}

await hackleClient.setUser(user);
```

## User Properties

The Hackle SDK supports adding user properties.

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

<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>

### Adding User Properties

You can add user properties simply. Calling the function below behaves the same as adding a property using `set` in a PropertyOperations object.

```javascript
await hackleClient.setUserProperty("gender", "female");
```

### Configuring 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 `PropertyOperationsBuilder` object with the user properties you want to configure. Then call `updateUserProperties` to update the user properties. You can also configure multiple properties at once.

```javascript
import { PropertyOperationsBuilder } from "@hackler/react-native-sdk"

const operations = new PropertyOperationsBuilder()
  .set("age", 42)
  .set("grade", "GOLD")
  .setOnce("sign_up_date", "2020-07-03")
  .build();

await hackleClient.updateUserProperties(operations);
```

## Resetting User

You must reset the previously configured information. Resetting clears all identifiers and properties that were previously set.

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

Assigning `undefined` to userId performs a client-side logout.
{% endhint %}

```javascript
await hackleClient.resetUser();
```


---

# Agent Instructions: 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:

```
GET https://docs.hackle.io/en/development-guide/react-native/user-identifier.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
