Migrate Adapty React Native SDK to v3.3
Adapty SDK 3.3.1 là bản phát hành lớn mang lại một số cải tiến có thể yêu cầu bạn thực hiện các bước migration.
- Nâng cấp lên Adapty SDK v3.3.x.
- Cập nhật các model.
- Xóa phương thức
getProductsIntroductoryOfferEligibility. - Cập nhật cách thực hiện giao dịch mua.
- Cập nhật cách hiển thị paywall trong Paywall Builder.
- Xem lại cách triển khai timer do developer định nghĩa.
- Cập nhật cách xử lý sự kiện mua hàng trong Paywall Builder.
- Cập nhật cách xử lý sự kiện custom action trong Paywall Builder.
- Sửa đổi callback
onProductSelected. - Xóa các tham số tích hợp bên thứ ba khỏi phương thức
updateProfile. - Cập nhật cấu hình tích hợp cho Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase and Google Analytics, Mixpanel, OneSignal, và Pushwoosh.
- Cập nhật cách triển khai Observer mode.
Nâng cấp Adapty React Native SDK lên 3.3.x
Trước phiên bản 3.3.1, SDK react-native-adapty là SDK cốt lõi và bắt buộc để Adapty hoạt động đúng trong ứng dụng của bạn. SDK @adapty/react-native-ui là tùy chọn và chỉ cần thiết nếu bạn sử dụng Adapty Paywall Builder.
Kể từ phiên bản 3.3.1, SDK @adapty/react-native-ui đã bị deprecated và chức năng của nó đã được tích hợp vào SDK react-native-adapty. Để nâng cấp lên phiên bản 3.3.1, hãy thực hiện các bước sau:
- Cập nhật gói
react-native-adaptylên phiên bản 3.3.1. - Xóa gói
@adapty/react-native-uikhỏi các dependency của dự án. - Đồng bộ hóa các dependency của dự án để áp dụng các thay đổi.
Thay đổi trong các model
Model mới
-
export interface AdaptySubscriptionOffer { readonly identifier: AdaptySubscriptionOfferId; phases: AdaptyDiscountPhase[]; android?: { offerTags?: string[]; }; } -
export type AdaptySubscriptionOfferId = | { id?: string; type: 'introductory'; } | { id: string; type: 'promotional' | 'win_back'; };
Model đã thay đổi
-
-
Đổi tên thuộc tính
subscriptionDetailsthànhsubscription.
- subscriptionDetails?: AdaptySubscriptionDetails; + subscription?: AdaptySubscriptionDetails; -
-
-
promotionalOfferđã bị xóa. Bây giờ ưu đãi chỉ được trả về trong thuộc tínhoffernếu có. Trong trường hợp đó,offer?.identifier?.typesẽ là'promotional'. -
introductoryOfferEligibilityđã bị xóa (ưu đãi chỉ được trả về nếu người dùng đủ điều kiện). -
offerIdđã bị xóa. ID ưu đãi hiện được lưu trongAdaptySubscriptionOffer.identifier. -
offerTagsđã được chuyển sangAdaptySubscriptionOffer.android.
- introductoryOffers?: AdaptyDiscountPhase[]; + offer?: AdaptySubscriptionOffer; ios?: { - promotionalOffer?: AdaptyDiscountPhase; subscriptionGroupIdentifier?: string; }; android?: { - offerId?: string; basePlanId: string; - introductoryOfferEligibility: OfferEligibility; - offerTags?: string[]; renewalType?: 'prepaid' | 'autorenewable'; }; } -
-
-
Trường
identifierđã bị xóa khỏi modelAdaptyDiscountPhase. Identifier của ưu đãi hiện được lưu trongAdaptySubscriptionOffer.identifier.
- ios?: { - readonly identifier?: string; - }; -
Xóa các model
AttributionSource:- Chuỗi string hiện được sử dụng ở những nơi trước đây dùng
AttributionSource.
- Chuỗi string hiện được sử dụng ở những nơi trước đây dùng
OfferEligibility:- Model này đã bị xóa vì không còn cần thiết. Hiện tại, ưu đãi chỉ được trả về nếu người dùng đủ điều kiện.
Xóa phương thức getProductsIntroductoryOfferEligibility
Trước Adapty SDK 3.3.1, các object sản phẩm luôn bao gồm ưu đãi, ngay cả khi người dùng không đủ điều kiện. Điều này yêu cầu bạn phải kiểm tra điều kiện thủ công trước khi sử dụng ưu đãi.
Kể từ phiên bản 3.3.1, object sản phẩm chỉ bao gồm ưu đãi nếu người dùng đủ điều kiện. Điều này đơn giản hóa quy trình vì bạn có thể giả định người dùng đủ điều kiện nếu có ưu đãi.
Cập nhật cách thực hiện giao dịch mua
Trong các phiên bản trước, giao dịch bị hủy và đang chờ xử lý được coi là lỗi và trả về mã 2: 'paymentCancelled' và 25: 'pendingPurchase' tương ứng.
Kể từ phiên bản 3.3.1, giao dịch bị hủy và đang chờ xử lý hiện được coi là kết quả thành công và nên được xử lý tương ứng:
try {
const purchaseResult = await adapty.makePurchase(product);
switch (purchaseResult.type) {
case 'success':
const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
}
break;
case 'user_cancelled':
// Handle the case where the user canceled the purchase
break;
case 'pending':
// Handle deferred purchases (e.g., the user will pay offline with cash)
break;
}
} catch (error) {
// Handle the error
}
Cập nhật cách hiển thị paywall trong Paywall Builder
Để xem các ví dụ cập nhật, hãy tham khảo tài liệu Hiển thị paywall mới từ Paywall Builder trong React Native.
- import { createPaywallView } from '@adapty/react-native-ui';
+ import { createPaywallView } from 'react-native-adapty/dist/ui';
const view = await createPaywallView(paywall);
view.registerEventHandlers(); // handle close press, etc
try {
await view.present();
} catch (error) {
// handle the error
}
Cập nhật cách triển khai timer do developer định nghĩa
Đổi tên tham số timerInfo thành customTimers:
- let timerInfo = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }
+ let customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }
//and then you can pass it to createPaywallView as follows:
- view = await createPaywallView(paywall, { timerInfo })
+ view = await createPaywallView(paywall, { customTimers })
Sửa đổi sự kiện mua hàng trong Paywall Builder
Trước đây:
- Giao dịch bị hủy kích hoạt callback
onPurchaseCancelled. - Giao dịch đang chờ xử lý trả về mã lỗi
25: 'pendingPurchase'.
Bây giờ:
- Cả hai trường hợp đều được xử lý bởi callback
onPurchaseCompleted.
Các bước migration:
- Xóa callback
onPurchaseCancelled. - Xóa phần xử lý mã lỗi
25: 'pendingPurchase'. - Cập nhật callback
onPurchaseCompleted:
const view = await createPaywallView(paywall);
const unsubscribe = view.registerEventHandlers({
// ... other optional callbacks
onPurchaseCompleted(purchaseResult, product) {
switch (purchaseResult.type) {
case 'success':
const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
}
break;
case 'user_cancelled':
// Handle the case where the user canceled the purchase
break;
case 'pending':
// Handle deferred purchases (e.g., the user will pay offline with cash)
break;
}
return purchaseResult.type !== 'user_cancelled';
},
});
Sửa đổi sự kiện custom action trong Paywall Builder
Các callback đã bị xóa:
onActiononCustomEvent
Callback mới được thêm vào:
- Callback
onCustomAction(actionId)mới. Sử dụng nó cho các custom action.
Sửa đổi callback onProductSelected
Trước đây, onProductSelected yêu cầu object product. Bây giờ yêu cầu productId dưới dạng chuỗi string.
Xóa các tham số tích hợp bên thứ ba khỏi phương thức updateProfile
Các identifier tích hợp bên thứ ba hiện được thiết lập bằng phương thức setIntegrationIdentifier. Phương thức updateProfile không còn chấp nhận chúng nữa.
Cập nhật cấu hình SDK tích hợp bên thứ ba
Để đảm bảo các tích hợp hoạt động đúng với Adapty React Native SDK 3.3.1 trở lên, hãy cập nhật cấu hình SDK của bạn cho các tích hợp sau đây như được mô tả trong các phần bên dưới.
Ngoài ra, nếu bạn đã sử dụng AttributionSource để lấy attribution identifier, hãy thay đổi code của bạn để cung cấp identifier cần thiết dưới dạng chuỗi string.
Adjust
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Adjust.
import { Adjust, AdjustConfig } from "react-native-adjust";
import { adapty } from "react-native-adapty";
var adjustConfig = new AdjustConfig(appToken, environment);
// Before submiting Adjust config...
adjustConfig.setAttributionCallbackListener(attribution => {
// Make sure Adapty SDK is activated at this point
// You may want to lock this thread awaiting of `activate`
adapty.updateAttribution(attribution, "adjust");
});
// ...
Adjust.create(adjustConfig);
+ Adjust.getAdid((adid) => {
+ if (adid)
+ adapty.setIntegrationIdentifier("adjust_device_id", adid);
+ });
AirBridge
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp AirBridge.
import Airbridge from 'airbridge-react-native-sdk';
import { adapty } from 'react-native-adapty';
try {
const deviceId = await Airbridge.state.deviceUUID();
- await adapty.updateProfile({
- airbridgeDeviceId: deviceId,
- });
+ await adapty.setIntegrationIdentifier("airbridge_device_id", deviceId);
} catch (error) {
// handle `AdaptyError`
}
Amplitude
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Amplitude.
import { adapty } from 'react-native-adapty';
try {
- await adapty.updateProfile({
- amplitudeDeviceId: deviceId,
- amplitudeUserId: userId,
- });
+ await adapty.setIntegrationIdentifier("amplitude_device_id", deviceId);
+ await adapty.setIntegrationIdentifier("amplitude_user_id", userId);
} catch (error) {
// handle `AdaptyError`
}
AppMetrica
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp AppMetrica.
import { adapty } from 'react-native-adapty';
import AppMetrica, { DEVICE_ID_KEY, StartupParams, StartupParamsReason } from '@appmetrica/react-native-analytics';
// ...
const startupParamsCallback = async (
params?: StartupParams,
reason?: StartupParamsReason
) => {
const deviceId = params?.deviceId
if (deviceId) {
try {
- await adapty.updateProfile({
- appmetricaProfileId: 'YOUR_ADAPTY_CUSTOMER_USER_ID',
- appmetricaDeviceId: deviceId,
- });
+ await adapty.setIntegrationIdentifier("appmetrica_profile_id", 'YOUR_ADAPTY_CUSTOMER_USER_ID');
+ await adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId);
} catch (error) {
// handle `AdaptyError`
}
}
}
AppMetrica.requestStartupParams(startupParamsCallback, [DEVICE_ID_KEY])
AppsFlyer
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp AppsFlyer.
import { adapty, AttributionSource } from 'react-native-adapty';
import appsFlyer from 'react-native-appsflyer';
appsFlyer.onInstallConversionData(installData => {
try {
- const networkUserId = appsFlyer.getAppsFlyerUID();
- adapty.updateAttribution(installData, AttributionSource.AppsFlyer, networkUserId);
+ const uid = appsFlyer.getAppsFlyerUID();
+ adapty.setIntegrationIdentifier("appsflyer_id", uid);
+ adapty.updateAttribution(installData, "appsflyer");
} catch (error) {
// handle the error
}
});
// ...
appsFlyer.initSdk(/*...*/);
Branch
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Branch.
import { adapty, AttributionSource } from 'react-native-adapty';
import branch from 'react-native-branch';
branch.subscribe({
enComplete: ({
params,
}) => {
- adapty.updateAttribution(params, AttributionSource.Branch);
+ adapty.updateAttribution(params, "branch");
},
});
Facebook Ads
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Facebook Ads.
import { adapty } from 'react-native-adapty';
import { AppEventsLogger } from 'react-native-fbsdk-next';
try {
const anonymousId = await AppEventsLogger.getAnonymousID();
- await adapty.updateProfile({
- facebookAnonymousId: anonymousId,
- });
+ await adapty.setIntegrationIdentifier("facebook_anonymous_id", anonymousId);
} catch (error) {
// handle `AdaptyError`
}
Firebase and Google Analytics
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Firebase and Google Analytics.
import analytics from '@react-native-firebase/analytics';
import { adapty } from 'react-native-adapty';
try {
const appInstanceId = await analytics().getAppInstanceId();
- await adapty.updateProfile({
- firebaseAppInstanceId: appInstanceId,
- });
+ await adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId);
} catch (error) {
// handle `AdaptyError`
}
Mixpanel
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Mixpanel.
import { adapty } from 'react-native-adapty';
import { Mixpanel } from 'mixpanel-react-native';
// ...
try {
- await adapty.updateProfile({
- mixpanelUserId: mixpanelUserId,
- });
+ await adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelUserId);
} catch (error) {
// handle `AdaptyError`
}
OneSignal
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp OneSignal.
Pushwoosh
Cập nhật code ứng dụng di động của bạn như hướng dẫn bên dưới. Để xem ví dụ code đầy đủ, hãy xem Cấu hình SDK cho tích hợp Pushwoosh.
import { adapty } from 'react-native-adapty';
import Pushwoosh from 'pushwoosh-react-native-plugin';
// ...
try {
- await adapty.updateProfile({
- pushwooshHWID: hwid,
- });
+ await adapty.setIntegrationIdentifier("pushwoosh_hwid", hwid);
} catch (error) {
// handle `AdaptyError`
}
Cập nhật cách triển khai Observer mode
Cập nhật cách bạn liên kết paywall với giao dịch. Trước đây, bạn sử dụng phương thức setVariationId để gán variationId. Bây giờ, bạn có thể đưa variationId trực tiếp khi ghi lại giao dịch bằng phương thức reportTransaction mới. Xem ví dụ code hoàn chỉnh trong Liên kết paywall với giao dịch mua trong Observer mode.
Đừng quên ghi lại giao dịch bằng phương thức reportTransaction. Bỏ qua bước này đồng nghĩa với việc Adapty sẽ không nhận ra giao dịch, không cấp mức độ truy cập, không đưa vào analytics, và không gửi đến các tích hợp. Đây là bước không thể bỏ qua!
Hãy lưu ý rằng thứ tự các tham số của phương thức reportTransaction khác với phương thức setVariationId.
const variationId = paywall.variationId;
try {
- await adapty.setVariationId(variationId, transactionId);
+ await adapty.reportTransaction(transactionId, variationId);
} catch (error) {
// handle the `AdaptyError`
}