Xử lý dữ liệu từ flow trong Capacitor SDK
Khi người dùng nhập vào trường input, trả lời câu hỏi trắc nghiệm, hoặc bật/tắt một toggle trong một flow, SDK sẽ truyền giá trị đó đến ứng dụng của bạn thông qua analytics callback.
Các ứng dụng thường sử dụng dữ liệu đó để:
- Đăng ký người dùng trên backend riêng: Lấy địa chỉ email và tên người dùng đã nhập trong flow onboarding, rồi tạo tài khoản cho họ khi flow đóng lại.
- Lưu câu trả lời và tùy chọn: Theo dõi những gì người dùng đã chọn để ứng dụng có thể sử dụng sau — ví dụ, ghi vào hồ sơ người dùng Adapty dưới dạng các thuộc tính tùy chỉnh.
- Tùy chỉnh các flow sau: Lưu câu trả lời từ quiz dưới dạng thuộc tính tùy chỉnh, rồi nhắm mục tiêu một placement sau để mỗi phân khúc nhận được một flow khác nhau, hoặc một paywall khác bên trong đó.
- Chuyển dữ liệu sang nền tảng analytics bên thứ ba: Chuyển tiếp câu trả lời đến Amplitude, Mixpanel, hoặc bất kỳ nền tảng product analytics nào bạn đang sử dụng.
Các input và selectable group tự động báo cáo giá trị của chúng. Để phân biệt các input trong code, hãy đặt cho mỗi input một Element ID có ý nghĩa và mỗi selectable group một Group ID trong builder.
Trước khi bắt đầu
Bạn cần:
- Adapty SDK v4 trở lên: Các flow callback không tồn tại trong các phiên bản cũ hơn.
- Một flow được xây dựng trong Flow & Paywall Builder: Chỉ có flow mới báo cáo các giá trị đầu vào thông qua callback này.
- Một phiên bản flow đã được xuất bản gần đây: Flow chỉ báo cáo các giá trị đầu vào nếu bạn xuất bản nó sau khi tính năng này có sẵn. Nếu không có gì đến được ứng dụng của bạn, hãy xuất bản một phiên bản mới của flow và thử lại.
Nhận giá trị đầu vào
Giá trị đầu vào được gửi đến cùng một handler như mọi sự kiện analytics khác từ một flow, với tên sự kiện là flow_user_input. Đăng ký onAnalytics cùng với các handler sự kiện flow khác của bạn:
view.setEventHandlers({
onAnalytics(name, params) {
handleFlowInput(name, params);
return false; // keep the flow open
},
});
Callback onAnalytics truyền tất cả các sự kiện analytics từ một flow, bao gồm cả lượt xem màn hình.
- Tham số
namechứa tên sự kiện. Để lọc các sự kiện nhập liệu của người dùng, hãy so sánhnamevớiflow_user_input. - Tham số
element_typecho biết danh mục của phần tử. - Giá trị đầu vào được lưu ở các tham số khác nhau tùy theo loại phần tử:
- Text field, picker và toggle lưu dữ liệu nhập của người dùng trong
value - Nhóm có thể chọn (selectable group) báo cáo các tùy chọn đang được chọn trong
item_idsvàitem_titles
- Text field, picker và toggle lưu dữ liệu nhập của người dùng trong
function handleFlowInput(name: string, params: Record<string, unknown>) {
if (name !== 'flow_user_input') return;
// The screen the input sits on. Pair it with element_id to tell apart
// two fields that share an Element ID on different screens.
const screenId = params.instanceId as string;
switch (params.element_type) {
case 'text_input':
case 'email_input':
case 'number_input':
case 'phone_input': {
const text = params.value as string;
break;
}
case 'date_picker':
case 'time_picker':
case 'date_time_picker': {
// Unix time in milliseconds.
const date = new Date(params.value as number);
break;
}
case 'single_choice': {
const optionId = (params.item_ids as string[])[0];
break;
}
case 'multi_choice': {
const optionIds = params.item_ids as string[];
break;
}
case 'toggle': {
const isOn = params.value as boolean;
break;
}
}
}
Để xác nhận callback được kích hoạt, hãy tương tác với input trong bản build thử nghiệm của ứng dụng. Nếu callback handler không nhận được sự kiện, hãy kiểm tra điều kiện tiên quyết. Đảm bảo rằng flow đã được xuất bản sau khi tính năng này có sẵn.
Khi ứng dụng nhận được dữ liệu đầu vào
Giá trị nhập mặc định hoặc lựa chọn mặc định sẽ không bao giờ được gửi đến ứng dụng của bạn thông qua callback này. Nếu người dùng chấp nhận tùy chọn được đánh dấu Set as default và tiếp tục, sẽ không có sự kiện nào được kích hoạt. Đừng coi việc thiếu sự kiện là “chưa trả lời” — người dùng chỉ đơn giản là giữ nguyên giá trị mặc định.
Các thành phần sau đây kích hoạt sự kiện này:
- Trường văn bản, email, số và điện thoại
- Bộ chọn ngày, giờ và ngày-giờ
- Nhóm lựa chọn đơn và đa lựa chọn, cùng với toggle
Các thành phần sau đây không kích hoạt:
- Trường mật khẩu, lựa chọn sản phẩm và chuyển tab
- Các trường nhập liệu bên trong phần tử Header, vốn được dùng chung trên nhiều màn hình
- Nhóm lựa chọn có Element ID trùng lặp hoặc bị thiếu, hoặc có Group ID được dùng lại trên màn hình khác. Nhóm như vậy sẽ không gửi gì cả, thay vì gửi một phần câu trả lời.
Sự kiện được kích hoạt khi:
- Một trường mất tiêu điểm (focus). Trường đã được xóa trắng sẽ báo cáo một chuỗi rỗng; trường người dùng chưa bao giờ chỉnh sửa sẽ không báo cáo gì. Placeholder không phải là giá trị. Nếu người dùng quay lại trường, chỉnh sửa rồi rời đi, một sự kiện thứ hai sẽ được gửi.
- Người dùng đóng bộ chọn sau khi chọn một giá trị mới. Đóng mà không thay đổi gì sẽ không báo cáo gì.
- Người dùng nhấn vào một tùy chọn hoặc toggle. Sự kiện đa lựa chọn liệt kê mọi tùy chọn đã được chọn, vì vậy việc bỏ chọn tùy chọn cuối cùng sẽ gửi hai mảng rỗng.
Sự kiện không được kích hoạt khi:
- Người dùng đang gõ. Không có luồng sự kiện gõ phím, chỉ có giá trị mà trường đang giữ khi tiêu điểm rời khỏi nó.
- Người dùng gửi hoặc đóng flow. Giá trị đang được chỉnh sửa tại thời điểm đó có thể bị mất; phần giới hạn gửi đề cập đến cách thiết kế màn hình cuối cùng xung quanh vấn đề này.
- Một giá trị được đặt mà không có tương tác của người dùng. Tùy chọn được đánh dấu Set as default được chọn sẵn khi màn hình mở ra, và hành động Set Variable có thể chọn một tùy chọn hoặc điền vào trường nhập liệu từ một tương tác khác. Cả hai đều không gửi sự kiện; trường được điền sẵn chỉ được báo cáo một lần khi người dùng chỉnh sửa nó.
Những gì bạn nhận được
Callback truyền hai sự kiện. Lọc theo name để chỉ hiển thị các sự kiện flow_user_input. Payload JSON trả về có dạng như sau:
{
"name": "flow_user_input",
"instanceId": "scr_registration",
"isBackendEvent": false,
"isCustomerEvent": true,
"element_id": "email",
"element_type": "email_input",
"value": "jane@example.com"
}
| Tham số | Mô tả |
|---|---|
name | flow_user_input cho sự kiện nhập liệu, flow_screen_showed cho lượt xem màn hình. |
instanceId | ID của màn hình chứa input. Element ID là duy nhất trong phạm vi một màn hình, không phải toàn bộ flow. Nếu flow của bạn có input trên nhiều màn hình, hãy kết hợp instanceId với element_id khi lọc sự kiện. |
element_id | Element ID của input, hoặc Group ID của nhóm có thể chọn. |
element_type | Loại element đã gửi sự kiện. Nó xác định tham số nào dưới đây chứa giá trị input. |
value | Chỉ dành cho text field, picker và toggle. Giá trị input: chuỗi ký tự cho text field, số nguyên cho picker, boolean cho toggle. |
item_ids | Chỉ dành cho nhóm single-choice và multi-choice. Element ID của các tùy chọn được chọn, theo thứ tự xuất hiện trong builder. Một mục cho nhóm single-choice; nhiều mục cho nhóm multi-choice. |
item_titles | Chỉ dành cho nhóm single-choice và multi-choice. Tiêu đề của các tùy chọn được liệt kê trong item_ids, theo cùng thứ tự. Không bao giờ rỗng: một tùy chọn không có tiêu đề sẽ báo cáo ID của nó. |
isCustomerEvent | Cờ tiện ích, luôn là true cho sự kiện này. Đánh dấu các sự kiện mà SDK truyền đến callback của bạn. Hữu ích nếu một handler chuyển tiếp mọi sự kiện flow đến analytics của bạn và bạn kiểm tra theo cờ này thay vì theo name. |
isBackendEvent | Cờ tiện ích, luôn là false cho sự kiện này. Đánh dấu các sự kiện mà Adapty cũng ghi lại cho analytics của riêng mình. false xác nhận rằng nội dung người dùng nhập chỉ đến ứng dụng của bạn và không đi đâu khác — Adapty không nhận hay lưu trữ nó. |
Những gì mỗi element báo cáo:
| Trong builder | element_type | Tham số lưu giá trị | Nội dung |
|---|---|---|---|
| Input Text, Number, Phone number | text_input, number_input, phone_input | value | Chuỗi ký tự thô người dùng đã nhập. Số đến dưới dạng chuỗi, không phải kiểu số. |
| Input E-mail | email_input | value | Chuỗi ký tự thô người dùng đã nhập, kể cả khi không vượt qua xác thực định dạng của builder. Hãy tự xác thực ở phía bạn trước khi sử dụng. |
| Input Password | none | none | Không gửi sự kiện. |
| Input Date | date_picker | value | Unix time tính bằng mili giây, dưới dạng số nguyên, tại nửa đêm theo giờ địa phương của ngày được chọn. |
| Input Time | time_picker | value | Unix time tính bằng mili giây, dưới dạng số nguyên, làm tròn xuống theo phút. |
| Input Date & Time | date_picker và time_picker | value | Hai element: một date picker và một time picker. Mỗi element gửi sự kiện riêng. |
| Input được chuyển sang Date & Time trong dropdown Type | date_time_picker | value | Unix time tính bằng mili giây, dưới dạng số nguyên, làm tròn xuống theo phút. |
| Nhóm Single choice | single_choice | item_ids, item_titles | Hai mảng. item_ids: mảng chứa Element ID của tùy chọn được chọn. item_titles: mảng chứa tiêu đề của tùy chọn đó. |
| Nhóm Multi-choice | multi_choice | item_ids, item_titles | Hai mảng. item_ids: Element ID của mọi tùy chọn được chọn, theo thứ tự xuất hiện trong builder. item_titles: tiêu đề của chúng, theo cùng thứ tự. Cả hai mảng đều rỗng khi không có gì được chọn. |
| Nhóm Toggle | toggle | value | Một boolean. |
Để phân nhánh theo câu trả lời, hãy so sánh item_ids, không phải item_titles. Tiêu đề được suy ra: Element Title của tùy chọn nếu bạn đã đặt, nếu không thì văn bản trong ngôn ngữ mặc định của bạn, nếu không thì Element ID của nó. Người dùng xem flow bằng ngôn ngữ khác sẽ thấy văn bản khác.
Ví dụ sự kiện
Các ví dụ sau đây minh họa các thuộc tính có sẵn trên từng sự kiện, với các giá trị minh họa trong phần bình luận.
Text, email, number, and phone input (Click to expand)
onAnalytics(name, params) {
name; // 'flow_user_input'
params.name; // 'flow_user_input'
params.instanceId; // 'scr_J260KU5q'
params.isCustomerEvent; // true
params.isBackendEvent; // false
params.element_id; // 'email'
params.element_type; // 'email_input'
params.value; // 'jane@example.com' (string)
} Bộ chọn ngày, giờ và ngày-giờ (Nhấn để mở rộng)
onAnalytics(name, params) {
params.element_id; // 'birthday'
params.element_type; // 'date_picker'
params.value; // 645408000000 (Unix milliseconds — 1990-06-15, local midnight)
} Single choice (Click to expand)
onAnalytics(name, params) {
params.element_id; // 'experience'
params.element_type; // 'single_choice'
params.item_ids; // ['pro']
params.item_titles; // ['I train professionally']
} Multi choice (Click to expand)
onAnalytics(name, params) {
params.element_id; // 'interests'
params.element_type; // 'multi_choice'
params.item_ids; // ['sports', 'music']
params.item_titles; // ['Sports', 'Music']
} Toggle (Click to expand)
onAnalytics(name, params) {
params.element_id; // 'reminders'
params.element_type; // 'toggle'
params.value; // true (boolean)
} Gửi dữ liệu và những hạn chế
Flow gửi dữ liệu thô — địa chỉ email, số điện thoại, và bất cứ thứ gì người dùng nhập vào. Hãy coi mọi thứ mà analytics callback trả về đều là dữ liệu cá nhân, và đừng lưu trữ chúng ở bất kỳ nơi nào bạn không muốn lưu địa chỉ email của người dùng.
- Giá trị cuối cùng được ưu tiên: Bạn nhận một sự kiện cho mỗi trường, mang theo giá trị mà người dùng đã chốt chứ không phải từng lần nhấn phím. Nếu họ chỉnh sửa một trường, chỉ phiên bản cuối cùng mới được gửi đến bạn.
- Không đảm bảo submit: Giá trị được gửi đến bạn khi người dùng di chuyển qua flow, và người dùng có thể thoát bất cứ lúc nào. Hãy đợi flow đóng lại trước khi coi một tập hợp câu trả lời là hoàn chỉnh.
- Gửi theo khả năng tốt nhất: Nếu người dùng đóng flow hoặc thu nhỏ ứng dụng trong khi một trường vẫn đang được focus hoặc một picker vẫn đang mở, giá trị đó có thể bị mất.
Để đảm bảo giá trị của trường cuối cùng luôn đáng tin cậy, hãy kết thúc flow bằng một màn hình không có ô nhập liệu và không có picker, đồng thời đóng flow bằng một thao tác rõ ràng của người dùng thay vì tự động đóng khi màn hình đó xuất hiện. Chuyển sang màn hình cuối sẽ lấy focus khỏi trường trước đó, đó chính là thao tác kích hoạt việc gửi giá trị.
Lưu từng giá trị đầu vào khi handler nhận được, rồi gửi toàn bộ dữ liệu khi flow đóng lại. Để bắt được thời điểm đó, hãy đăng ký handler onDisappeared cùng với onAnalytics. Handler này chạy khi view của flow bị đóng, dù người dùng hoàn thành flow hay thoát ra giữa chừng.
Các trường hợp sử dụng
Đăng ký người dùng trên backend của bạn
Thu thập các giá trị khi chúng xuất hiện và gửi chúng đi một lần sau khi flow đóng lại, để một request duy nhất mang đầy đủ tất cả các câu trả lời.
Flow sẽ biến mất dù người dùng đã hoàn thành hay bỏ dở giữa chừng. Hãy kiểm tra các trường bạn cần trước khi gọi backend.
Flow không thể hiển thị lỗi từ backend của bạn. Giá trị trả về của handler chỉ đóng view flow lại, và SDK không có phương thức nào gửi dữ liệu vào một flow đang chạy. Nếu việc đăng ký thất bại, ví dụ như do email đã được sử dụng, hãy hiển thị lỗi trong giao diện của chính bạn sau khi flow đóng lại.
const flowAnswers: Record<string, string> = {};
view.setEventHandlers({
onAnalytics(name, params) {
if (name === 'flow_user_input' && typeof params.value === 'string') {
flowAnswers[params.element_id as string] = params.value;
}
return false;
},
onDisappeared() {
if (flowAnswers.email) {
// Send flowAnswers to your backend here to create the account.
}
return false;
},
});
Làm phong phú thêm hồ sơ người dùng với dữ liệu
Để liên kết thông tin người dùng đã nhập vào hồ sơ của họ và tránh hỏi lại những thông tin đã có, hãy cập nhật hồ sơ người dùng ngay khi nhận được giá trị.
Ví dụ: nếu flow của bạn có ô nhập văn bản với Element ID là name và ô nhập email với Element ID là email:
function handleFlowInput(name: string, params: Record<string, unknown>) {
if (name !== 'flow_user_input') return;
if (typeof params.value !== 'string') return;
const profileParams: Partial<AdaptyProfileParameters> = {};
switch (params.element_id) {
case 'name':
profileParams.firstName = params.value;
break;
case 'email':
profileParams.email = params.value;
break;
default:
return;
}
adapty.updateProfile(profileParams).catch((error) => {
// handle the error
});
}
Tùy chỉnh các flow được hiển thị sau này
Câu trả lời trong quiz cũng có thể quyết định những gì người dùng thấy ở một placement sau — một flow khác, hoặc một paywall khác bên trong nó.
Ví dụ: hỏi người dùng về kinh nghiệm tập thể thao của họ trong flow onboarding, sau đó hiển thị cho mỗi nhóm một flow riêng với các sản phẩm và nội dung khác nhau.
- Thêm một quiz vào flow của bạn. Đặt nhóm có thể chọn với Group ID là
experience, và mỗi tùy chọn có một Element ID có ý nghĩa. - Xử lý các câu trả lời và thiết lập thuộc tính tùy chỉnh cho người dùng.
function handleFlowInput(name: string, params: Record<string, unknown>) {
if (name !== 'flow_user_input') return;
if (params.element_id !== 'experience') return;
const optionId = (params.item_ids as string[])[0];
adapty
.updateProfile({
// Set the custom attribute 'experience' to the option the user selected
// (beginner, amateur, or pro).
codableCustomAttributes: { experience: optionId },
})
.catch((error) => {
// handle the error
});
}
- Tạo một phân khúc cho mỗi giá trị thuộc tính tùy chỉnh.
- Tạo một placement và thêm một đối tượng cho mỗi phân khúc.
- Hiển thị flow cho placement đó trong ứng dụng của bạn.