# Expo SDK 基本集成指南

本节包含有关如何将 Pushwoosh Expo SDK 集成到您的应用程序中的信息。

## 先决条件

要将 Pushwoosh Expo SDK 集成到您的应用中，您需要以下内容：

<Aside type="note" title="要求">
 - 一个 [Pushwoosh 账户](https://sso.pushwoosh.com/login)。
 - 在您的账户中设置一个 [Pushwoosh 项目](/zh/product/first-steps/start-with-your-project/create-your-project)。
 - **对于 iOS 集成：**
    - 配置为发送推送通知的 iOS 平台。我们建议使用[基于令牌的身份验证配置](/zh/developer/first-steps/connect-messaging-services/ios-configuration/ios-token-based-configuration/)作为最简单的方法。
    - 将网关设置为 `Sandbox` 以向模拟器发送推送。
 - **对于 Android 集成：**
    - 一个[已配置的 Android 平台](/zh/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 Application Code` 和来自 Pushwoosh 控制面板的 [Pushwoosh Device API Token](/zh/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](/zh/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 控制面板并[发送一条推送通知](/zh/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 上的富媒体等功能至关重要。

请遵循[原生指南的步骤](/zh/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 自定义通知图标的路径 |

## 故障排除

如果您在集成过程中遇到任何问题，请参阅[支持和社区](/zh/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
```