Troubleshooting

If you are having trouble integrating the SDK, uploading your certificates or sending notifications, here are some suggestions.

Displaying a stable debug ID

The Installation ID is an ID generated by Batch for all the installs the first time your users open the app. You can safely display it in your app to simplify the debug process.

You can use that ID in the debug tool (Dashboard settings > Debug) to find your own install, see the data Batch has on it and send test notifications to your device.

Your end users can also send it to you so you can understand why they are not receiving push notifications or not seeing an In-App message. This is useful when your app doesn't share any advertising ID with Batch.

Debug iOS

You can also store the install ID on your end and reuse it later to target specific installs using the Transactional API.

Retrieving the installation ID

You can retrieve the installation ID by calling the following methods:

  • Swift
  • Objective-C
BatchUser.installationID()

Displaying the installation ID

That installation ID can be exposed to your end users. You can insert it in a diagnostic email automatically generated when users report an issue from the app or hide it in an easter egg.

Example

Copying the installation ID

1.18 Batch will now copy the installation ID to the clipboard when the application appears in the foreground 4 times within 20 seconds. This is enabled by default, you can disable it at any time by using:

  • Swift
  • Objective-C
class AppDelegate: UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // This can be called at any time, even before starting Batch.
        Batch.setEnablesFindMyInstallation(false)
        // ...
    }
}

Enabling internal logs

1.17 Internal logs can be useful to you or our support team to debug issues that might not be debuggable using public logs. They're disabled by default as they are very verbose by design.

They can be enabled in two ways:

Using code

  • Swift
  • Objective-C
class AppDelegate: UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // This can be called at any time, even before starting Batch.
        // Enabling logs as early as possible ensures that you don't miss important events.
        Batch.setInternalLogsEnabled(true)
        // ...
    }
}

Note: Please make sure that you do not enable internal logs on an App Store build.

Using a command line argument

Command line arguments are only usable when an app is launched by Xcode or while running tests. This is an easy way to make sure that logs never end up in a production build. However, they cannot be allow for internal logs to be read by testers.

Batch will enable internal logs if the app has been launched with -BatchSDKEnableInternalLogs:

Adding the command line flag using Xcode's sheme editor

Implementing Batch debugger

The debug view is a UI with multiple debug features, allowing you to see the native and custom data attached to your install. You can also see the list of In-App campaigns already stored in your device.

Debugger overview

This is useful for development purposes and for internal uses only, especially if your team cannot use an advertising or a custom user id to find their device in the debug tool and send test notifications to their device.

Identifiers

Debugger native data

Shows a list of native information you can use for basic debug:

  • Batch SDK version
  • Installation ID
  • Advertising ID
  • Push token
  • APN Environment

You can easily share that report by clicking the share button in the top right corner.

Custom user data

Debugger custom data

Shows the custom user data attached to your install, excluding events. This is useful to:

  • Check the Custom User ID attached to the install (see more here).
  • See the list of attributes / tag collections attached to your install. You can use that part to see if the app has been tagged correctly or understand why your device didn't receive a notification based on a one of these information.

In-App campaigns

Debugger in-app

Use that part to manually pull the campaigns available on Batch servers for your install and to see the list of stored In-App campaigns.

Implementing the debugger

The debugger should be presented modally:

  • Swift
  • Swift
  • Objective-C
if let debugVC = Batch.debugViewController() {
    present(debugVC, animated: true, completion: nil)
}

You can hide it in an easter egg (e.g. display it after 10 taps on specific button, etc) or simply display it in your app settings for your development versions exclusively.

Common issues

I’m not seeing any data on my dashboard

There are several points you should check if Batch doesn't show any data on your dashboard:

  • Dev/Live API key. Make sure that you used the Live API key in the build you uploaded to the store. Stats are only displayed for the Live API key.
  • 24h delay. Installs, DAU, starts and redeems shown on the Analytics tab are updated on a 24h basis for the Live API key.
  • Integration issue. If you still don't see any stats for your app 24h after changing the API key, see if you find anything related to Batch in your logs and double check your integration using the documentation.

"Unable to find a token"

There are several points you should check if Batch doesn't detect any device tokens:

  • Push disabled: See if you have enabled the notifications for your app in the iOS settings (Settings → Notifications).
  • Look for errors: Check your Xcode logs to see if Batch published any error messages.
  • Provisioning issue: Make sure you have correctly set up your provisioning profile with Xcode.

My device doesn't seem to receive any notifications

If you are not receiving any of the notifications sent from Batch, here are some suggestions to find the issue:

  • App opened: Make sure your app is not opened in the foreground during your tests. By default iOS only displays notifications for apps opened in the background: It only calls your delegate, which can be invisible to you if you don't log anything.
  • Push disabled: See if you have enabled the notifications for your app in iOS settings (Settings → Notifications).
  • Connection issues: Connect your device to a 3G/4G network or try to disconnect/reconnect to your WiFi network.
  • Test notifications: Try to send a test notification to your device from the message editor ("Push" tab → "New push campaign" → "Send a test").

I'm receiving notifications twice

You may receive the same notification twice if you have reinstalled your app with different API keys, several times on the same device (Dev/Live). Rest assured, your users won't receive the same notification twice.

Certificates issues

The .p12 export button is greyed out

Make sure you have selected the default login keychain in the left pane of the Keychain application, and selected "My certificates" in the top filtering bar of the Keychain application.

"Wrong file or password"

First, double check your certificate password. If your password is correct, make sure your certificate is not named "Apple Production IOS Push Services" or "Apple Development IOS Push Services". These are not supported anymore. You will need to generate a new production certificate if it's the case.

"Unable to parse the p12"

You cannot upload Apple's certificate directly. You will find more information on certificate generation here.

“Legacy or development certificates are no longer supported”

Development certificates or production certificates named "Apple Production IOS Push Services" are not supported anymore. Please generate a new .p8 certificate.

Test push issues

"DeviceTokenNotForTopic"

DeviceTokenNotForTopic errors happen when your app's bundle ID and certificate's bundle ID don't match.

Bundle ID

Please ensure you set up your bundle ID correctly in your Xcode project settings.

"BadDeviceToken"

BadDeviceToken errors can happen for two reasons:

  • Invalid token: On iOS 9 and higher, your device token may change if you uninstall/reinstall an app. Please make sure your token hasn't changed since your last tests. See how to obtain your token here.
  • Wrong environment: If your device token is valid, make sure you have chosen the right environment (sandbox/production) from Batch settings (Settings → Push settings). You can find the right environment for your token with our debug tool.

"The attempt to send a [test] notification was rejected : invalid certificate"

If you see an "Invalid certificate" error, this means that:

  • Legacy certificates: You are currently using a legacy certificate and the Development or the Production certificates are missing.
  • Delay: Batch is still processing your certificates. Please try again in a few minutes and reach us if the problem persists.

"There was an unknown error while processing the request"

If you are getting an unknown error, please contact us at support@batch.com or by clicking on the question mark in the bottom right corner. Our team will try to find more details on the issue.

APNS/internal errors

You can find the list of APNS and Batch internal errors in the Notifications tab, by hovering on the error count.

apns_invalid_token

APNS can send this feedback when:

  • Invalid token: The token Batch tries to push is not valid anymore. This usually happens when users uninstall/reinstall (iOS 9.x and higer) your app or disable notifications.
  • Wrong environment: Make sure you are targeting the right environment (sandbox/production) for your token.

apns2_device_token_not_for_topic

Happens when your app's bundle ID and certificate's bundle ID don't match. Make sure you set up your bundle ID correctly in your Xcode project settings.

apns2_topic_disallowed

Make sure the App ID/Bundle ID or the team ID you used for your P8 certificate are correct.

max_retry_attempts

This internal error happens when the number of maximum send attempts is reached for a token. Feel free to reach us if you are seeing to many max_retry_attemps errors.