> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tappd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting the Tappd Mobile SDK for React Native

> Fix common Tappd Mobile SDK problems on React Native, iOS, and Android — from initialization failures to push token errors and AsyncStorage issues.

Most integration problems fall into a small number of categories. Work through the accordion below that matches your symptom, apply the fix, and re-test. If you're still stuck, the **Getting Help** section at the bottom explains exactly what information to gather before contacting support.

## Common Issues

<Accordion title="SDK Not Initializing — 'App ID is required'">
  **Symptom:** The SDK throws `"App ID is required"` on startup and no events reach the dashboard.

  The most common cause is instantiating `TappdSDK` with an empty or missing `appId`.

  <CodeGroup>
    ```javascript Wrong theme={null}
    // ❌ Missing appId — SDK cannot initialize
    const tappd = new TappdSDK({});
    ```

    ```javascript Correct theme={null}
    // ✅ Always pass your appId
    const tappd = new TappdSDK({
      appId: 'YOUR_APP_ID'
    });
    ```
  </CodeGroup>

  **Checklist:**

  1. Copy your App ID from the Tappd dashboard — do not type it manually.
  2. Confirm the value is not `undefined` or an empty string at runtime (log it to verify).
  3. Confirm you are importing the SDK correctly: `import TappdSDK from '@tappd/mobile-sdk'`.
</Accordion>

<Accordion title="Events Not Tracking — Events Not Appearing in Dashboard">
  **Symptom:** `track()` resolves without throwing, but no events appear in the Tappd dashboard.

  Work through these fixes in order:

  **1. Enable debug mode** to see SDK activity in your console:

  ```javascript theme={null}
  const tappd = new TappdSDK({
    appId: 'YOUR_APP_ID',
    debug: true
  });
  ```

  **2. Check network requests** using React Native Debugger or Flipper's Network tab. Verify that requests are being sent and returning `2xx` status codes.

  **3. Verify the API URL** matches Tappd's hosted endpoint:

  ```javascript theme={null}
  const tappd = new TappdSDK({
    appId: 'YOUR_APP_ID',
    apiUrl: 'https://sdk.gotappd.com/api/v1/sdk'
  });
  ```

  **4. Await every `track()` call.** Dropping the `await` means errors are silently swallowed.

  <CodeGroup>
    ```javascript Wrong theme={null}
    // ❌ Fire-and-forget — errors are not surfaced
    tappd.track('event');
    ```

    ```javascript Correct theme={null}
    // ✅ Await so you can catch errors
    await tappd.track('event');
    ```
  </CodeGroup>
</Accordion>

<Accordion title="Anonymous Data Not Merging After Identification">
  **Symptom:** Events tracked before `identify()` are not linked to the identified user profile.

  The merge only happens when `identify()` is called with at least `external_id`. Check both points below.

  **Ensure you pass `external_id` to `identify()`:**

  ```javascript theme={null}
  // Events tracked while anonymous
  await tappd.track('event_1');
  await tappd.track('event_2');

  // Call identify with external_id — this triggers the merge
  await tappd.identify({
    external_id: 'user_123',
    email: 'john@example.com'
  });
  ```

  **Verify the anonymous ID is stable** (it should be the same value across calls before identification):

  ```javascript theme={null}
  const anonymousId = tappd.getAnonymousId();
  console.log('Anonymous ID:', anonymousId);
  ```

  If the anonymous ID changes between calls, AsyncStorage is not persisting correctly — see the **AsyncStorage Issues** section below.
</Accordion>

<Accordion title="Session Issues — Sessions Not Starting or Expiring Incorrectly">
  **Symptom:** Sessions appear missing in the dashboard, or they expire far too quickly.

  **Adjust `sessionTimeout`** if sessions are expiring too soon (value is in minutes):

  ```javascript theme={null}
  const tappd = new TappdSDK({
    appId: 'YOUR_APP_ID',
    sessionTimeout: 60 // 60-minute timeout
  });
  ```

  **Verify a session is active** immediately after initialization — the value should never be `null`:

  ```javascript theme={null}
  const sessionId = tappd.getSessionId();
  console.log('Session ID:', sessionId);
  // Expected: sess_abc123... — not null
  ```

  If `getSessionId()` returns `null`, the SDK failed to initialize. Go back to the **SDK Not Initializing** section.
</Accordion>

<Accordion title="Screen Tracking Not Working — Screen Views Missing">
  **Symptom:** Only some screens are tracked, or screen views are absent even though `trackScreen()` is called.

  **Use `useFocusEffect` instead of `useEffect`.** With `useEffect`, the screen view fires only on mount. With `useFocusEffect`, it fires every time the screen comes into focus — which is what you want in a tab or stack navigator.

  ```javascript theme={null}
  import { useFocusEffect } from '@react-navigation/native';

  function MyScreen() {
    useFocusEffect(
      React.useCallback(() => {
        tappd.trackScreen('MyScreen');
      }, [])
    );
  }
  ```

  **Also check:**

  * `NavigationContainer` is configured at the root of your app.
  * Screen names are consistent across all calls (casing matters).
</Accordion>

<Accordion title="Push Token Registration Fails — 'User must be identified first'">
  **Symptom:** `registerPushToken()` throws `"User must be identified first"`.

  `registerPushToken()` requires an identified user. Always call `identify()` before you register the token.

  ```javascript theme={null}
  // ✅ Correct order: identify first, then register
  await tappd.identify({
    external_id: 'user_123',
    email: 'john@example.com'
  });

  await tappd.registerPushToken(token, 'ios');
  ```

  **Also verify your platform configuration:**

  * **iOS:** Confirm APNs push certificates are uploaded to Firebase.
  * **Android:** Confirm `google-services.json` is in `android/app/`.
  * **Both:** Log the token to confirm it is not null or empty:

  ```javascript theme={null}
  const token = await messaging().getToken();
  console.log('FCM Token:', token);
  ```
</Accordion>

<Accordion title="AsyncStorage Issues — New Anonymous ID on Every Launch">
  **Symptom:** Each app launch generates a new anonymous ID, making it impossible to merge pre-identification events.

  The SDK relies on `@react-native-async-storage/async-storage` to persist the anonymous ID. If it is missing or misconfigured, a new ID is generated on every launch.

  **Install the package:**

  ```bash theme={null}
  npm install @react-native-async-storage/async-storage
  cd ios && pod install && cd ..
  ```

  **Verify AsyncStorage is working correctly:**

  ```javascript theme={null}
  import AsyncStorage from '@react-native-async-storage/async-storage';

  AsyncStorage.setItem('test', 'value').then(() => {
    AsyncStorage.getItem('test').then((value) => {
      console.log('AsyncStorage works:', value === 'value');
    });
  });
  ```

  If the log prints `false`, AsyncStorage is not functioning — check for linking errors and re-run `pod install`.
</Accordion>

<Accordion title="Build Errors — iOS and Android">
  **iOS build failures:**

  Run `pod install` after adding or updating the SDK:

  ```bash theme={null}
  cd ios && pod install && cd ..
  ```

  For a full clean build, remove the derived data and Pods directories first:

  ```bash theme={null}
  cd ios
  rm -rf build
  rm -rf Pods
  pod install
  cd ..
  ```

  **Android build failures:**

  Clean the Gradle cache:

  ```bash theme={null}
  cd android
  ./gradlew clean
  cd ..
  ```

  Then check for version conflicts between `@tappd/mobile-sdk` and other packages in your `package.json`.
</Accordion>

<Accordion title="TypeScript Errors — Type Errors in TypeScript Projects">
  **Symptom:** TypeScript reports missing types or unknown properties when using the SDK.

  Import SDK types directly from the package — no separate `@types` install is needed:

  ```typescript theme={null}
  import TappdSDK, { TappdConfig, CustomerAttributes } from '@tappd/mobile-sdk';

  const config: TappdConfig = {
    appId: 'YOUR_APP_ID'
  };

  const tappd = new TappdSDK(config);
  ```

  If you still see errors after the correct import, install the React Native community types:

  ```bash theme={null}
  npm install --save-dev @types/react-native
  ```
</Accordion>

***

## Debug Mode

Enable `debug: true` when you initialize the SDK to stream detailed logs to your React Native console. These logs are the fastest way to confirm the SDK is working as expected.

```javascript theme={null}
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  debug: true
});
```

With debug mode on, you should see messages like these:

```
[Tappd SDK] Initialized with App ID: a1b2c3d4...
[Tappd SDK] New session started: sess_abc123
[Tappd SDK] Event tracked: purchase
[Tappd SDK] Customer identified: user_123
```

If any of these lines are absent, that step failed — use the relevant accordion above to fix it.

<Note>
  Disable `debug: true` before releasing to production to avoid leaking internal SDK logs to end users.
</Note>

***

## Getting Help

If you've worked through the relevant section above and the problem persists, contact Tappd support. To get a fast resolution, gather the following before reaching out:

<Steps>
  <Step title="Check your logs">
    Open the React Native debugger and copy any SDK-related log output.
  </Step>

  <Step title="Enable debug mode">
    Set `debug: true`, reproduce the issue, and capture the full log output.
  </Step>

  <Step title="Verify network requests">
    Use Flipper or Chrome DevTools Network tab to confirm whether API requests are being sent and what responses they receive.
  </Step>

  <Step title="Check your SDK version">
    Run `npm list @tappd/mobile-sdk` and confirm you are on the latest release.
  </Step>

  <Step title="Contact support with these details">
    * Full error messages
    * Platform (iOS, Android, or both)
    * React Native version (`npx react-native --version`)
    * Tappd SDK version
    * Debug logs from steps 1–2
  </Step>
</Steps>

***

## Common Error Messages

| Error                             | Cause                                                                               | Fix                                                                                    |
| --------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `"App ID is required"`            | `appId` is missing or empty in `TappdConfig`                                        | Copy your App ID from the Tappd dashboard                                              |
| `"User must be identified first"` | Called `registerPushToken()`, `setUserAttributes()`, or similar before `identify()` | Call `identify()` before any method that requires an identified user                   |
| `"Request failed: ..."`           | Network failure or API error                                                        | Check your `apiUrl`, verify internet connectivity, and inspect the response in Flipper |
| `"AsyncStorage error"`            | `@react-native-async-storage/async-storage` not installed or linked                 | Install the package and run `pod install` on iOS                                       |
