---
title: "OneSignal"
description: "Tích hợp OneSignal với Adapty để cải thiện tương tác dựa trên thông báo đẩy."
---

[OneSignal](https://onesignal.com/) là nền tảng tương tác khách hàng hàng đầu, cung cấp thông báo đẩy, email, SMS và tin nhắn trong ứng dụng. Tích hợp Adapty với OneSignal cho phép bạn truy cập tất cả các sự kiện gói đăng ký ở một nơi, giúp bạn kích hoạt giao tiếp tự động dựa trên những sự kiện đó.

Với Adapty, bạn có thể theo dõi [các sự kiện gói đăng ký](events) trên nhiều cửa hàng, phân tích hành vi người dùng và sử dụng dữ liệu đó để giao tiếp có mục tiêu hơn. Tích hợp này giúp bạn theo dõi các sự kiện gói đăng ký trong dashboard OneSignal và ánh xạ chúng tới [các chiến dịch thu hút](https://documentation.onesignal.com/docs/en/automated-messages).

Adapty cập nhật các tag của OneSignal dựa trên sự kiện gói đăng ký, giúp bạn gửi thông báo đẩy được cá nhân hóa với cài đặt tối thiểu.

**Đặc điểm tích hợp**

| Đặc điểm tích hợp | Mô tả |
| :------------------------- | :----------------------------------------------------------- |
| Lịch trình | Cập nhật theo thời gian thực |
| Chiều dữ liệu | Một chiều: từ Adapty sang máy chủ OneSignal |
| Điểm tích hợp Adapty | <ul><li>SDK của OneSignal và Adapty trong mã ứng dụng di động</li><li>Máy chủ Adapty</li></ul>|

## Thiết lập tích hợp OneSignal \{#setting-up-one-signal-integration\}

Để thiết lập tích hợp:

1. Mở [Integrations → OneSignal](https://app.adapty.io/integrations/onesignal) trong Adapty Dashboard của bạn.

   
     <img src="/assets/shared/img/onesignal-on.webp"
     style={{
       border: '1px solid #727272', /* border width and color */
       width: '700px', /* image width */
       display: 'block', /* for alignment */
       margin: '0 auto' /* center alignment */
     }}
   />
   

2. Bật nút chuyển đổi tích hợp.
3. Nhập **OneSignal App ID** của bạn.

Để thiết lập tích hợp với OneSignal, vào [Integrations -> OneSignal](https://app.adapty.io/integrations/onesignal) trong Adapty dashboard của bạn, bật nút chuyển đổi và cấu hình thông tin xác thực tích hợp.

## Lấy OneSignal App ID của bạn \{#retrieving-your-onesignal-app-id\}

Tìm **OneSignal App ID** của bạn trong [OneSignal Dashboard](https://dashboard.onesignal.com/login):

1. Điều hướng đến **Settings** → **Keys & IDs**.

   
     <img src="/assets/shared/img/onesignal-dashboard.webp"
     style={{
       border: '1px solid #727272', /* border width and color */
       width: '700px', /* image width */
       display: 'block', /* for alignment */
       margin: '0 auto' /* center alignment */
     }}
   />
   

2. Sao chép **OneSignal App ID** của bạn và dán vào trường **App ID** trong Adapty Dashboard.

   
     <img src="/assets/shared/img/onesignal-id.webp"
     style={{
       border: '1px solid #727272', /* border width and color */
       width: '700px', /* image width */
       display: 'block', /* for alignment */
       margin: '0 auto' /* center alignment */
     }}
   />
   

Bạn có thể tìm thêm thông tin về OneSignal ID trong [tài liệu sau.](https://documentation.onesignal.com/docs/en/keys-and-ids)

### Cấu hình sự kiện \{#configuring-events\}

Adapty cho phép bạn gửi ba nhóm sự kiện tới OneSignal. Bật những sự kiện bạn cần trong Adapty Dashboard. Bạn có thể xem danh sách đầy đủ các sự kiện có sẵn kèm mô tả chi tiết [tại đây](events).

  <img src="/assets/shared/img/onesignal.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

Adapty gửi các sự kiện gói đăng ký tới OneSignal thông qua tích hợp server-to-server, cho phép bạn theo dõi toàn bộ hoạt động liên quan đến gói đăng ký trong OneSignal.

:::warning

Bắt đầu từ ngày 17 tháng 4 năm 2023, Gói Miễn phí của OneSignal không còn hỗ trợ tích hợp này. Tính năng này chỉ có trên các gói **Growth**, **Professional** và **cao hơn**. Để biết chi tiết, xem [Bảng giá OneSignal](https://onesignal.com/pricing).

:::

## Tag tùy chỉnh \{#custom-tags\}

Tích hợp này cập nhật và gán nhiều thuộc tính cho người dùng Adapty của bạn dưới dạng tag, sau đó được gửi tới OneSignal. Tham khảo danh sách tag bên dưới để tìm những tag phù hợp nhất với nhu cầu của bạn.
:::warning
OneSignal có giới hạn số lượng tag. Điều này bao gồm cả các tag do Adapty tạo ra và các tag hiện có trong OneSignal. Vượt quá giới hạn có thể gây ra lỗi khi gửi sự kiện.
:::

| Tag | Kiểu | Mô tả |
|---|----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `adapty_customer_user_id` | String | Mã định danh duy nhất của người dùng trong ứng dụng của bạn. Phải nhất quán trong toàn hệ thống, Adapty và OneSignal. |
| `adapty_profile_id` | String | ID hồ sơ người dùng Adapty, có sẵn trong [Adapty Dashboard](profiles-crm). |
| `environment` | String | `Sandbox` hoặc `Production`, cho biết môi trường hiện tại của người dùng. |
| `store` | String | Cửa hàng nơi sản phẩm được mua. Các tùy chọn: **app_store**, **play_store**, **stripe**, hoặc tên [cửa hàng tùy chỉnh](custom-store) của bạn. |
| `vendor_product_id` | String | ID sản phẩm trong cửa hàng ứng dụng (ví dụ: `org.locals.12345`). |
| `subscription_expires_at` | String | Ngày hết hạn của gói đăng ký mới nhất (`YYYY-MM-DDTHH:MM:SS+0000`, ví dụ: `2023-02-10T17:22:03.000000+0000`). |
| `last_event_type` | String | Loại sự kiện mới nhất từ [danh sách sự kiện Adapty](events).<br/> Lưu ý những điều sau:<br/>- Đối với sự kiện **Subscription expired**, Adapty gửi thuộc tính `last_event_type` là `subscription_cancelled`.<br/>- Đối với **Trial renew canceled** – là `auto_renew_off`<br/>- Đối với **Subscription renew canceled** – là `auto_renew_off_subscription` |
| `purchase_date` | String | Ngày giao dịch gần nhất (`YYYY-MM-DDTHH:MM:SS+0000`, ví dụ: `2023-02-10T17:22:03.000000+0000`). |
| `active_subscription` | String | `true` nếu người dùng có gói đăng ký đang hoạt động và `false` nếu gói đăng ký đã hết hạn. |
| `period_type` | String | Cho biết loại kỳ gần nhất cho lần mua hoặc gia hạn. Các giá trị có thể: `trial` cho thời gian dùng thử hoặc `normal` cho tất cả các trường hợp khác. |

Tất cả các giá trị float được làm tròn thành số nguyên. Các chuỗi vẫn giữ nguyên.

Ngoài các tag đã định sẵn, bạn có thể gửi [thuộc tính tùy chỉnh](segments#custom-attributes) dưới dạng tag, mang lại sự linh hoạt hơn trong dữ liệu bạn đưa vào. Điều này hữu ích cho việc theo dõi các chi tiết cụ thể liên quan đến sản phẩm hoặc dịch vụ của bạn.

Các thuộc tính người dùng tùy chỉnh được tự động gửi tới OneSignal nếu checkbox **Send user attributes** được bật trên [trang tích hợp](https://app.adapty.io/integrations/onesignal). Khi không được chọn, Adapty gửi đúng 10 tag. Nếu được chọn, có thể gửi hơn 10 tag, cho phép thu thập dữ liệu phong phú hơn.

## Cấu hình SDK \{#sdk-configuration\}

Có hai cách để tích hợp OneSignal với Adapty:

1. **Legacy (trước v5):** Sử dụng `playerId` (đã deprecated trong [OneSignal SDK v5](https://github.com/OneSignal/OneSignal-iOS-SDK/releases/tag/5.0.0)).
2. **Hiện tại (v5+):** Sử dụng `subscriptionId`.

:::warning
Đảm bảo gửi `playerId` (cho OneSignal SDK trước v5) hoặc `subscriptionId` (cho OneSignal SDK v5+) tới Adapty. Nếu không có điều này, các tag OneSignal sẽ không được cập nhật và tích hợp sẽ không hoạt động đúng.
:::

<Tabs groupId="current-version" queryString> 
<TabItem value="v5+" label="OneSignal SDK v5+ (current)" default> 

<Tabs groupId="current-os" queryString>
<TabItem value="swift" label="iOS (Swift)" default>

```swift showLineNumbers
// SubscriptionID
OneSignal.Notifications.requestPermission({ accepted in
    Task {
        // Adapty SDK 4.x
        try await Adapty.setIntegrationIdentifier(.oneSignalSubscriptionId(OneSignal.User.pushSubscription.id))
        // Adapty SDK 3.x
        try await Adapty.setIntegrationIdentifier(
            key: "one_signal_subscription_id", 
            value: OneSignal.User.pushSubscription.id
        )
    }
}, fallbackToSettings: true)
```

</TabItem>
<TabItem value="kotlin" label="Android (Kotlin)" default>

```kotlin showLineNumbers
// SubscriptionID
val oneSignalSubscriptionObserver = object: IPushSubscriptionObserver {
    override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) {
        Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.current.id) { error ->
            if (error != null) {
                // handle the error
            }
        }
    }
}
```

</TabItem>
<TabItem value="java" label="(Android) Java" default>

```java showLineNumbers
// SubscriptionID
IPushSubscriptionObserver oneSignalSubscriptionObserver = state -> {
    Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.getCurrent().getId(), error -> {
        if (error != null) {
            // handle the error
        }
    });
};
```

</TabItem>  

<TabItem value="flutter" label="Flutter (Dart)" default>

```javascript showLineNumbers
// 1. Since OneSignal.User.pushSubscription.id may return null if called too early, 
// OneSignal suggests to listen for the updates:

OneSignal.User.pushSubscription.addObserver((state) {
   if (state.current.optedIn) {
      // now you can try to retrieve subscriptionId
   }
});

// 2. Then you can push subscriptionId to Adapty:
final subscriptionId = OneSignal.User.pushSubscription.id;
if (subscriptionId != null) {
   await Adapty().setIntegrationIdentifier(key: "one_signal_subscription_id", value: subscriptionId);
}
```

</TabItem>
<TabItem value="unity" label="Unity (C#)" default>

```csharp showLineNumbers
using AdaptySDK;
using OneSignalSDK;

var pushUserId = OneSignal.Default.PushSubscriptionState.userId;

Adapty.SetIntegrationIdentifier(
  "one_signal_player_id", 
  pushUserId, 
  (error) => {
  // handle the error
});
```

</TabItem>
<TabItem value="rn" label="React Native (TS)" default>

```typescript showLineNumbers

OneSignal.User.pushSubscription.addEventListener('change', (subscription) => {
  const subscriptionId = subscription.current.id;

  if (subscriptionId) {
    adapty.setIntegrationIdentifier("one_signal_subscription_id", subscriptionId);
  }
});
```

</TabItem>
</Tabs>

 </TabItem> 

<TabItem value="pre-v5" label="OneSignal SDK v. up to 4.x (legacy)" default> 

<Tabs groupId="current-os" queryString>
<TabItem value="swift" label="iOS (Swift)" default>

```swift showLineNumbers
// PlayerID
// in your OSSubscriptionObserver implementation
func onOSSubscriptionChanged(_ stateChanges: OSSubscriptionStateChanges) {
    if let playerId = stateChanges.to.userId {
        Task {
            // Adapty SDK 4.x
            try await Adapty.setIntegrationIdentifier(.oneSignalPlayerId(playerId))
            // Adapty SDK 3.x
            try await Adapty.setIntegrationIdentifier(
                key: "one_signal_player_id", 
                value: playerId
            )
        }
    }
}
```

</TabItem>
<TabItem value="kotlin" label="Android (Kotlin)" default>

```kotlin showLineNumbers
// PlayerID
val osSubscriptionObserver = OSSubscriptionObserver { stateChanges ->
    stateChanges?.to?.userId?.let { playerId ->
        Adapty.setIntegrationIdentifier("one_signal_player_id", playerId) { error ->
            if (error != null) {
                // handle the error
            }
        }
    }
}
```

</TabItem>
<TabItem value="java" label="Java" default>

```java showLineNumbers
// PlayerID
OSSubscriptionObserver osSubscriptionObserver = stateChanges -> {
    OSSubscriptionState to = stateChanges != null ? stateChanges.getTo() : null;
    String playerId = to != null ? to.getUserId() : null;
    
    if (playerId != null) {
        Adapty.setIntegrationIdentifier("one_signal_player_id", playerId, error -> {
            if (error != null) {
                // handle the error
            }
        });
    }
};
```

</TabItem>  

<TabItem value="flutter" label="Flutter (Dart)" default>

```javascript showLineNumbers
// PlayerID (pre-v5 OneSignal SDK)
// in your OSSubscriptionObserver implementation
func onOSSubscriptionChanged(_ stateChanges: OSSubscriptionStateChanges) {
    if let playerId = stateChanges.to.userId {
        Task {
            try await Adapty.setIntegrationIdentifier(
                key: "one_signal_player_id", 
                value: playerId
            )
        }
    }
}
```

</TabItem>
<TabItem value="rn" label="React Native (TS)" default>
```typescript showLineNumbers

OneSignal.addSubscriptionObserver(event => {
  const playerId = event.to.userId;
  
  adapty.setIntegrationIdentifier("one_signal_player_id", playerId);
});
```

</TabItem>
</Tabs>

 </TabItem> 

</Tabs>

Đọc thêm trong tài liệu OneSignal:

- [Push subscription ID](https://documentation.onesignal.com/docs/en/mobile-sdk-reference#user-pushsubscription-id)
- [Thay đổi push subscription](https://documentation.onesignal.com/docs/en/mobile-sdk-reference#addobserver-push-subscription-changes)

## Xử lý nhiều thiết bị \{#dealing-with-multiple-devices\}

Khi một người dùng có nhiều thiết bị, việc theo dõi sự kiện mua hàng và gói đăng ký có thể là thách thức. OneSignal cung cấp cách xử lý vấn đề này thông qua [external user IDs](https://documentation.onesignal.com/docs/en/users).

Để giữ dữ liệu người dùng nhất quán trên các thiết bị:

1. Khớp các thiết bị khác nhau ở **phía máy chủ** của bạn và gửi dữ liệu này tới OneSignal.
2. Sử dụng [customer_user_id](identifying-users) của Adapty làm [externalUserId](https://documentation.onesignal.com/docs/en/users#external-id) trong OneSignal. Nếu ứng dụng của bạn không có hệ thống đăng ký, hãy cân nhắc sử dụng một mã định danh duy nhất khác vẫn nhất quán trên tất cả thiết bị của người dùng.

Điều quan trọng là duy trì sự nhất quán của mã định danh người dùng trên tất cả thiết bị và cập nhật OneSignal mỗi khi ID của người dùng thay đổi. Điều này đơn giản hóa việc theo dõi hoạt động và gói đăng ký của người dùng, đồng thời đảm bảo tin nhắn nhất quán và cho phép phân tích chính xác hơn cũng như trải nghiệm người dùng tốt hơn. Để biết thêm chi tiết, xem [tài liệu external user ID của OneSignal](https://documentation.onesignal.com/docs/en/users).