# Expo SDK 기본 통합 가이드

이 섹션에서는 Pushwoosh Expo SDK를 애플리케이션에 통합하는 방법에 대한 정보를 제공합니다.

## 전제 조건

Pushwoosh Expo SDK를 앱에 통합하려면 다음이 필요합니다:

<Aside type="note" title="요구 사항">
 - [Pushwoosh 계정](https://sso.pushwoosh.com/login).
 - 계정에 설정된 [Pushwoosh 프로젝트](/ko/product/first-steps/start-with-your-project/create-your-project).
 - **iOS 통합의 경우:**
    - 푸시 알림을 보내도록 구성된 iOS 플랫폼. 가장 간단한 접근 방식으로 [토큰 기반 인증 구성](/ko/developer/first-steps/connect-messaging-services/ios-configuration/ios-token-based-configuration/)을 사용하는 것을 권장합니다.
    - 시뮬레이터로 푸시를 보내려면 게이트웨이를 `Sandbox`로 설정하세요.
 - **Android 통합의 경우:**
    - [구성된 Android 플랫폼](/ko/developer/first-steps/connect-messaging-services/android-configuration/android-firebase-configuration)
    - Firebase 프로젝트의 `google-services.json` 파일과 `package name`.
    - Android 애플리케이션에 연결된 Firebase 프로젝트. 필요한 경우 [Firebase 설정 가이드](https://firebase.google.com/docs/android/setup#manually_add_firebase)를 따르세요.
 - 애플리케이션의 Pushwoosh 제어판에서 가져온 `Pushwoosh Application Code` 및 [Pushwoosh Device API Token](/ko/developer/api-reference/api-access-token/#device-api-token).
</Aside>

## 통합 단계

### 1. 플러그인 설치

Expo CLI를 사용하여 Pushwoosh Expo 플러그인을 설치합니다.

```bash
expo install pushwoosh-expo-plugin
```

Pushwoosh React Native SDK를 설치합니다.

```bash
npm install pushwoosh-react-native-plugin --save
```

### 2. 플러그인 속성 설정

필요한 속성과 함께 플러그인 배열의 맨 앞에 플러그인을 추가합니다:

```json title="app.json/app.config.js"
{
  "expo": {
    "plugins": [
      [
        "pushwoosh-expo-plugin",
        {
          "mode": "development",
          "ios": {
            "PW_API_TOKEN": "__YOUR_DEVICE_API_TOKEN__"
          },
          "android": {
            "apiToken": "__YOUR_DEVICE_API_TOKEN__"
          }
        }
      ]
    ]
  }
}
```
여기서:

- `mode`는 APNs 환경 자격을 구성하는 데 사용됩니다. "Development" 또는 "production" 값을 사용할 수 있습니다.
- `PW_API_TOKEN`, `apiToken`은 [Pushwoosh Device API Token](/ko/developer/api-reference/api-access-token/#device-api-token)입니다.

### 3. Pushwoosh 초기화

애플리케이션의 루트 컴포넌트에서:
- `pushwoosh-react-native-plugin` 플러그인을 가져옵니다.
- Pushwoosh SDK를 초기화합니다.
- 초기화 로직에서 `register()`를 호출하여 푸시 알림에 등록합니다.

```javascript title="index.tsx"
import Pushwoosh from 'pushwoosh-react-native-plugin';

Pushwoosh.init({
    "pw_appid": "__YOUR_APP_ID__"
});

Pushwoosh.register();
```
여기서:
- `__YOUR_APP_ID__`는 Pushwoosh 제어판의 애플리케이션 코드입니다.

### 4. Android 네이티브 설정

Firebase 구성 파일을 추가합니다:

1. `google-services.json` 파일을 프로젝트의 루트 디렉터리로 복사합니다.
2. `googleServicesFile` 속성을 `google-services.json`의 경로로 설정하고 `package` 속성을 지정합니다:

```json title="app.json/app.config.js"
  "expo": {
    "name": "sample",
  "android": {
    "package": "com.pushwoosh.sample",
    "googleServicesFile": "./google-services.json"
  },
  "plugins": [
    [
      "pushwoosh-expo-plugin",
      {
        "mode": "development",
        "ios": {
          "PW_API_TOKEN": "__YOUR_DEVICE_API_TOKEN__"
        },
        "android": {
          "apiToken": "__YOUR_DEVICE_API_TOKEN__"
        }
      }
    ]
  ]
}
```

### 5. iOS 네이티브 설정

`bundleIdentifier` 속성을 `ios` 객체에 설정합니다:

```json title="app.json/app.config.js"
  "expo": {
    "name": "sample",
    "ios": {
      "bundleIdentifier": "com.pushwoosh.sample"
    },
    "plugins": [
    [
      "pushwoosh-expo-plugin",
      {
        "mode": "development",
        "ios": {
          "PW_API_TOKEN": "__YOUR_DEVICE_API_TOKEN__"
        },
        "android": {
          "apiToken": "__YOUR_DEVICE_API_TOKEN__"
        }
      }
    ]
  ]
}
```

### 6. 앱 사전 빌드
prebuild를 실행하여 네이티브 코드를 생성하고 각 플랫폼의 종속성을 구성합니다:
```bash
npx expo prebuild
```

### 7. 프로젝트 실행

1. 프로젝트를 빌드하고 실행합니다:
<Tabs>
<TabItem label="Android">
```bash
npx expo run:android
```
</TabItem>

<TabItem label="iOS">
```bash
npx expo run:ios
```
</TabItem>
</Tabs>

2. Pushwoosh 제어판으로 이동하여 [푸시 알림을 보냅니다](/ko/product/messaging-channels/push-notifications/send-push-notifications/one-time-push).
3. 앱에서 알림을 볼 수 있어야 합니다.

## 확장 통합

이 단계에서는 이미 SDK를 통합하여 푸시 알림을 보내고 받을 수 있습니다. 이제 핵심 기능을 살펴보겠습니다.

### 푸시 알림 이벤트 리스너

Pushwoosh SDK에는 푸시 알림 처리를 위해 설계된 두 개의 이벤트 리스너가 있습니다:

- `onPushReceived` 이벤트는 푸시 알림이 수신될 때 트리거됩니다.
- `onPushAccepted` 이벤트는 사용자가 알림을 열 때 트리거됩니다.

애플리케이션 시작 시 SDK 초기화 직후에 이러한 이벤트 리스너를 설정해야 합니다:

```typescript
import { DeviceEventEmitter } from 'react-native';
import Pushwoosh from 'pushwoosh-react-native-plugin';

class PushwooshNotificationHandler {
  setupPushListeners(): void {

    DeviceEventEmitter.addListener("pushReceived", (e) => {
      console.warn("Push received: " + JSON.stringify(e));
    });

    DeviceEventEmitter.addListener("pushOpened", (e) => {
      console.warn("Push opened:" + JSON.stringify(e));
    });

  }
}
```

### 사용자 구성

개별 사용자 행동과 선호도에 초점을 맞춤으로써 개인화된 콘텐츠를 제공하여 사용자 만족도와 충성도를 높일 수 있습니다.

```typescript
import Pushwoosh from 'pushwoosh-react-native-plugin';

class Registration {
  afterUserLogin(user: User): void {

    // Set user ID
    Pushwoosh.setUserId(user.getId());

    // Set user email
    Pushwoosh.setEmails(user.getEmailList());

    // Setting additional user information as tags for Pushwoosh
    Pushwoosh.setTags({
      "age": user.getAge(),
      "name": user.getName(),
      "last_login": user.getLastLoginDate()
    });
  }
}
```

### 태그

태그는 사용자나 기기에 할당된 키-값 쌍으로, 선호도나 행동과 같은 속성을 기반으로 세분화를 가능하게 하여 타겟 메시징을 할 수 있습니다.

```typescript
import Pushwoosh from 'pushwoosh-react-native-plugin';

class UpdateUser {
  afterUserUpdateProfile(user: User): void {

    // Set list of favorite categories
    Pushwoosh.setTags({
      "favorite_categories": user.getFavoriteCategoriesList()
    });

    // Set payment information
    Pushwoosh.setTags({
      "is_subscribed": user.isSubscribed(),
      "payment_status": user.getPaymentStatus(),
      "billing_address": user.getBillingAddress()
    });
  }
}
```

### 이벤트

이벤트는 앱 내에서 발생하는 특정 사용자 행동이나 사건으로, 행동을 분석하고 해당 메시지나 작업을 트리거하기 위해 추적할 수 있습니다.

```typescript
import Pushwoosh from 'pushwoosh-react-native-plugin';

class Registration {

  // Track login event
  afterUserLogin(user: User): void {
    Pushwoosh.postEvent("login", {
      "name": user.getName(),
      "last_login": user.getLastLoginDate()
    });
  }

  // Track purchase event
  afterUserPurchase(product: Product): void {
    Pushwoosh.postEvent("purchase", {
      "product_id": product.getId(),
      "product_name": product.getName(),
      "price": product.getPrice(),
      "quantity": product.getQuantity()
    });
  }
}
```

### iOS 메시지 전송 추적

프로젝트에 Notification Service Extension 타겟을 추가해야 합니다. 이는 정확한 전송 추적 및 iOS의 Rich Media와 같은 기능에 필수적입니다.

[네이티브 가이드의 단계](/ko/developer/pushwoosh-sdk/ios-sdk/setting-up-pushwoosh-ios-sdk/basic-integration-guide/#4-message-delivery-tracking)에 따라 확장 타겟과 그 안에 필요한 Pushwoosh 코드를 추가하세요.

### 추가 플러그인 속성

| 속성 <div style="width:180px"></div> | 기본값 <div style="width:100px"></div> | 설명 |
|-----------------|---------|-------------|
| **iOS 속성** | | |
| `Pushwoosh_LOG_LEVEL` | `INFO` | iOS용 로그 수준. 가능한 값: `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `NOISE` |
| **Android 속성** | | |
| `logLevel` | `INFO` | Android용 로그 수준. 다음 중 하나: `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `NOISE` |
| `multiNotificationMode`| `true` | 사용자에게 마지막 알림만 표시하려는 경우 false로 변경할 수 있습니다. |
| `icon` | - | Android용 사용자 지정 알림 아이콘 경로 |

## 문제 해결

통합 과정에서 문제가 발생하면 [지원 및 커뮤니티](/ko/developer/pushwoosh-sdk/support-and-community) 섹션을 참조하세요.

###### FCM registration error: Failed to retrieve token. Is firebase configured correctly?

Firebase `googleServicesFile` 속성이 Expo 구성 파일에 설정되어 있고 `google-services.json` 파일이 프로젝트의 루트 디렉터리에 추가되었는지 확인하세요:
```json title="app.json/app.config.js"
"expo": {
  "name": "sample",
  "android": {
    "package": "com.pushwoosh.sample",
    "googleServicesFile": "./google-services.json"
  },
  "plugins": [
    [
      "pushwoosh-expo-plugin",
      {
        "mode": "development",
        "ios": {
          "PW_API_TOKEN": "__YOUR_DEVICE_API_TOKEN__"
        },
        "android": {
          "apiToken": "__YOUR_DEVICE_API_TOKEN__"
        }
      }
    ]
  ]
}
```

###### TypeError: Cannot read property 'init' of null

기기에서 앱을 실행하려고 할 때 이 오류가 발생할 수 있습니다.\
문제를 해결하려면 사전 빌드 단계를 완료했는지 확인하세요. 이 단계는 네이티브 코드를 생성하고 각 플랫폼의 종속성을 구성합니다.

```bash
npx expo prebuild
```