---
title: "Thứ tự gọi trong Kotlin Multiplatform SDK"
description: "Tránh mất quyền truy cập premium, thiếu attribution, và lỗi kích hoạt gián đoạn bằng cách gọi các phương thức Adapty SDK theo đúng thứ tự."
---

`Adapty.activate()` phải hoàn tất trước khi bạn gọi bất kỳ phương thức Adapty SDK nào khác. Cho đến khi hoàn tất, SDK chưa có trạng thái. Bất kỳ lệnh gọi nào được thực hiện trước hoặc song song với `activate()` đều sẽ thất bại với lỗi kích hoạt. Xem [Xử lý lỗi trong Kotlin Multiplatform SDK](kmp-handle-errors).

Nếu ứng dụng của bạn xác thực người dùng và bạn thu thập customer user ID sau khi khởi chạy, hãy gọi `Adapty.identify()` tại thời điểm đó. Đừng gọi các phương thức liên quan đến hành động người dùng cho đến khi `identify` hoàn tất. Các lệnh gọi chạy đua với nó sẽ trả về lỗi hoặc rơi vào hồ sơ người dùng ẩn danh được tạo lúc kích hoạt. Khi điều này xảy ra, attribution, MMP ID như `appsflyer_id`, và quyền sở hữu lượt cài đặt không phải lúc nào cũng được chuyển sang hồ sơ người dùng đã xác định. Nếu ứng dụng không xác thực người dùng, bỏ qua `identify` và tiếp tục làm việc với hồ sơ người dùng ẩn danh.

Các SDK MMP và analytics (AppsFlyer, Adjust, Branch, PostHog) tuân theo quy tắc tương tự. Khởi tạo chúng trước và chờ callback UID của chúng trước khi gọi `Adapty.activate`. Nếu không, MMP ID sẽ rơi vào hồ sơ người dùng ẩn danh tồn tại trong thời gian ngắn và không phải lúc nào cũng được chuyển sang hồ sơ người dùng đã xác định. Để biết chi tiết về AppsFlyer, xem [AppsFlyer](appsflyer).

## Thứ tự đúng \{#the-correct-order\}

Luồng của bạn phụ thuộc vào hai yếu tố: thời điểm bạn biết customer user ID và liệu bạn có sử dụng SDK MMP hoặc analytics hay không.

- **Bước 2 và 5**: Bắt buộc với mọi ứng dụng. Kích hoạt SDK, sau đó gọi các phương thức SDK.
- **Bước 1 và 3**: Chỉ cần thiết nếu bạn tích hợp SDK MMP hoặc analytics (AppsFlyer, Adjust, Branch, PostHog).
- **Bước 4**: Chỉ cần thiết nếu ứng dụng của bạn xác thực người dùng và thu thập customer user ID sau khi khởi chạy.

Nếu bạn đã có customer user ID lúc khởi chạy ứng dụng, hãy truyền nó vào `AdaptyConfig.Builder` trước khi gọi `activate()` (bước 2a). Luồng này không bao giờ tạo hồ sơ người dùng ẩn danh, nên bước 4 là không cần thiết.

| Bước | Lệnh gọi                                                                                                      | Thời điểm                                                                              | Lưu ý                                                                                          |
|------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| 1    | Khởi tạo SDK MMP hoặc analytics của bạn (AppsFlyer, Adjust, PostHog, Branch)                                  | Khi khởi chạy ứng dụng, thực hiện đầu tiên                                            | Chờ callback UID của MMP, ví dụ `getAppsFlyerUID`.                                             |
| 2a   | `Adapty.activate(configuration = AdaptyConfig.Builder("KEY").withCustomerUserId(...).build())`                | Khi khởi chạy ứng dụng, sau bước 1, nếu bạn đã có customer user ID                   | Khuyến nghị. Không bao giờ tạo hồ sơ người dùng ẩn danh.                                      |
| 2b   | `Adapty.activate(configuration = AdaptyConfig.Builder("KEY").build())` không có `withCustomerUserId`          | Khi khởi chạy ứng dụng, sau bước 1, nếu bạn chưa có customer user ID (hoặc không thu thập) | Adapty tạo hồ sơ người dùng ẩn danh.                                                          |
| 3    | `Adapty.setIntegrationIdentifier("appsflyer_id", uid)` cho mỗi MMP                                            | Sau bước 2, trước bất kỳ lệnh gọi hành động người dùng nào                            | Bắt buộc để MMP ID được ghi vào đúng hồ sơ người dùng.                                        |
| 4    | `Adapty.identify("YOUR_USER_ID").onSuccess { ... }.onError { ... }`                                           | Sau bước 3 (hoặc bước 2 nếu không có MMP), trước bước 5 — chỉ trên luồng 2b có xác thực | Chờ `onSuccess` trước bất kỳ lệnh gọi hành động người dùng nào. Các lệnh gọi đồng thời trong quá trình `identify` có thể rơi vào hồ sơ người dùng ẩn danh. |
| 5    | `getPaywall`, `getPaywallProducts`, `restorePurchases`, `makePurchase`, `updateAttribution`, `updateProfile`  | Sau bước 4 nếu bạn gọi `identify`; nếu không thì sau bước 3 (hoặc bước 2 nếu không có MMP) | Các lệnh gọi này cần một hồ sơ người dùng ổn định.                                            |

:::important
Bỏ qua các bước này sẽ khiến người dùng quay lại mất quyền truy cập premium, `appsflyer_id` bị thiếu trên hồ sơ người dùng, và paywall được trả về cho sai đối tượng.
:::

## Cài đặt từ web2app và web funnel \{#web2app-and-web-funnel-installs\}

Nếu người dùng mua hàng qua web checkout (Stripe, Paddle) và sau đó cài đặt ứng dụng native, lần đầu tiên `activate()` trên thiết bị sẽ tạo một hồ sơ người dùng ẩn danh mới. Hồ sơ người dùng này không được liên kết với hồ sơ người dùng web. Nếu bạn có thể xác định customer user ID trước khi khởi chạy ứng dụng (từ luồng xác thực hoặc install referrer), hãy truyền trực tiếp vào `AdaptyConfig.Builder`. Nếu không, lần mua hàng trên web sẽ không hiển thị trên thiết bị cho đến khi bạn gọi `identify("YOUR_USER_ID")` và sau đó gọi `restorePurchases`.

Để biết metadata cần gửi với mỗi web checkout, xem:

- [Stripe](stripe)
- [Paddle](paddle)