Skip to content
reception

Search documentation

Loading documentation…

    Log in
    Browse documentation

    Resources

    Troubleshooting

    Find the symptom you see, check the relevant configuration, and verify the result with a real chat. These checks apply to the current Reception SDK and Reception's hosted service.

    View Markdown

    Check first

    For developers and coding agents, before changing code:

    1. Find Reception.configure(appId:). It runs once at launch on the main actor, before other Reception calls, with the App ID from Settings → your app → General.

    2. Reproduce the problem and read the Reception logs of that launch. In Xcode, filter the console for Reception. On a simulator:

    Terminal
    xcrun simctl spawn <device> log show --last 2m --info --style compact --predicate 'subsystem BEGINSWITH "com.reception"'
    1. If messages don't arrive, run the setup check in a Debug simulator build, signed as Xcode normally signs it. It sends one real message, "Hello from setup":

    Terminal
    xcrun simctl launch --terminate-running-process <device> <bundle identifier> -ReceptionSetupCheck <App ID>

    Read the logs every 10 seconds, for up to 70 seconds. Only a result from this launch counts.

    ResultMeaning
    Setup check passedReception received the message.
    Setup check failed: app_id_mismatchThe app configures a different App ID than the one you passed. Check which one is right in the dashboard.
    Setup check failed: send_not_allowedSending is blocked, for example because only verified users may chat or the device is blocked.
    Setup check failed: not_deliveredThe SDK's log lines before it name the reason.
    Setup check failed: app_not_active or timeoutThe app didn't reach the foreground, or Reception didn't answer.
    No resultThe check didn't start: the build isn't a Debug simulator build, or configure didn't run.

    On Android, Reception.configure(context, appId) belongs in Application.onCreate; Flutter and React Native configure from Dart or JavaScript at startup. Read the logs with adb logcat -s Reception (set Reception.logLevel = Reception.LogLevel.DEBUG for details) and run the setup check on a debuggable build, with your app's package and launcher activity. The last line of adb shell cmd package resolve-activity --brief <package> is the <package>/<launcher activity> to pass after -n; when the Gradle namespace differs from the package, use that full class name, because the short form <package>/.MainActivity fails. The command is the same for native, Flutter and React Native apps:

    Terminal
    adb shell am start -S -n <package>/<launcher activity> --es ReceptionSetupCheck <App ID>
    adb logcat -d -s Reception

    The results are the same as above. No result on Android means the build isn't debuggable or configure didn't run: in a native app before the launcher activity was created, in Flutter or React Native at startup.

    The setup check proves only that messages reach Reception. Check the Support button, colors, user details and push on their own. Don't use logout() or deleteData() to fix a connection problem.

    Chat does not open

    Reception.shared.openChat() presents the SDK chat sheet over the current screen. Configure Reception before calling it. An entry point such as a settings row or floating button belongs to your app.

    If your app presents ReceptionChatView() itself, use your own sheet binding or navigation state to open and dismiss it. Reception.shared.openChat() and Reception.shared.closeChat() control only the SDK-owned sheet.

    Check Entry point for both presentation patterns. Verify that tapping your entry point shows the chat and that Reception.shared.isChatOpen becomes true while it is visible.

    On Android

    Reception.openChat() needs an activity of your app in the foreground and a configured SDK; called from the background or before configure, it does nothing. A second call while the sheet is up does nothing too. If a paywall or dialog your app shows from onPaywall appears under the chat, call Reception.closeChat() before showing it. An embedded ReceptionChatView with a composer hidden by the keyboard needs an edge-to-edge activity (enableEdgeToEdge()) or adjustResize.

    Swift reports a main actor isolation error

    The Reception facade and ReceptionChatView are main-actor isolated. Call SDK APIs from main-actor code. Notification delegate callbacks may need to hop to the main actor; preserve your existing delegate and completion handling.

    For a callback that only needs to request presentation, this belongs inside the host app's callback implementation:

    Swift
    Task { @MainActor in
        Reception.shared.openChat()
    }

    Use the complete notification examples in Push notifications when handling push payloads. See SDK reference for the public API surface.

    No user or conversation appears in the dashboard

    Identification, metadata updates, and opening an unused chat do not register a new device; configuration does, while the app is active (SDK 1.6+). Reception starts registration on the first valid send attempt; the first successful message creates a conversation. Fetching remote appearance can happen before this and does not prove registration succeeded.

    Send a short message and confirm it reaches Sent. Then check the dashboard's organization, selected app, search, status, and development-device filters. A registered device without a successful message is not a completed chat setup. See Get started and Dashboard.

    The first message fails or the chat stays connecting

    Check that Reception.configure(appId:) ran before SDK use, with the App ID of the intended app from Settings → your app → General in the dashboard.

    Your simulator and development iPhone connect to the same hosted Reception service, which uses HTTPS in production. Check the device’s internet connection and copy the setup snippet again if needed; replace only the App ID in public documentation examples. See Get started.

    An available network doesn't mean chat is connected. Offline and connecting states reflect different conditions. For a previously used chat, keep the app foregrounded and the chat open while restoring connectivity; the SDK reconnects and attempts supported retries automatically. The connection status is hidden for an unused chat.

    If the problem persists, tell us what happens when you send a message and any error message you see. You do not need to find an HTTP status or internal error code. A wrong App ID requires updating configuration. Do not use logout or data deletion as a network repair: they change the support session. See Chat features.

    Use the App ID shown in the dashboard. After correcting configuration, relaunch and retry. If the app was deleted or Reception reports it unavailable, contact us; retries cannot restore a deleted app.

    On Android 7.0

    Android 7.0 (API 24) itself is older than the root certificates of Let’s Encrypt, which sign the Reception service’s HTTPS certificates. Devices on exactly that version refuse the connection, so the chat stays connecting, messages show as not delivered and photos fail to upload. Android 7.1.1 and later need nothing.

    The SDK never changes which certificates your app trusts. If your app still serves Android 7.0, add Let’s Encrypt’s two roots to your app’s own network security configuration. Download ISRG Root X1 and ISRG Root X2 in PEM format from letsencrypt.org/certificates, save them as res/raw/isrg_root_x1.pem and res/raw/isrg_root_x2.pem, and trust them next to the system’s certificates:

    res/xml/network_security_config.xml
    <network-security-config>
        <base-config>
            <trust-anchors>
                <certificates src="system" />
                <certificates src="@raw/isrg_root_x1" />
                <certificates src="@raw/isrg_root_x2" />
            </trust-anchors>
        </base-config>
    </network-security-config>

    Register the file with android:networkSecurityConfig="@xml/network_security_config" on the <application> element in AndroidManifest.xml. If your app already has such a file, add the two <certificates> lines to its <trust-anchors> instead. In Flutter and React Native apps these files belong to the Android project (android/app/src/main).

    Send is disabled or a message cannot be sent

    An empty or whitespace-only message without photos cannot be sent. Wait for photo loading to finish, keep at most five photos, and keep text within 4,000 characters; some emoji count as two.

    If the chat says sending is unavailable, inspect the device's blocked state in the dashboard. Blocking prevents customer messages and uploads while retaining access to history. A team member must unblock the device; retrying does not bypass the block. The open chat updates when it synchronizes after unblocking; the draft remains unsent.

    For a failed message, use its Retry action after addressing the cause. For a temporary sending limit, follow the chat's waiting notice and retry when it's available; repeated taps don't shorten the wait. See Chat features.

    The chat asks the customer to sign in

    "Sign in to send messages." replaces the composer when your app requires verified users and Reception reports that this device is unverified. The customer can still read any existing conversation. Call Reception.shared.identify(token:) after sign-in and on every launch while a user is signed in, and check your event handler for identityRejected. To let everyone chat again, turn off Only verified users can chat in the dashboard. See Identity verification.

    Photos fail while text works

    “Could not load this photo.” means the SDK could not read or decode a selected photo. Select another photo that the device can load and wait for processing to finish before sending.

    Photo uploads use storage managed by Reception. Check the device's internet connection, then retry the failed message. If it still fails, try a small photo. Tell us whether text messages work, what happens when you send the photo, and any error message you see. You do not need an upload error code. The SDK's picker, image preparation, upload, and message send are separate steps; successful text delivery does not verify photo delivery.

    See Chat features for photo behavior and limits.

    Unread counts or app badges look stale

    Unread monitoring starts with Reception.configure(appId:). The SDK checks unread on launch and foreground once registered, and polls only an open conversation. After support has started, foregrounding refreshes the device and unread state. Opening the chat marks messages read when the server request succeeds; unread checks alone do not mark messages read.

    Automatic unread checks run for recently active, open conversations while your app is foregrounded and chat is hidden. They pause when push is configured and notification permission is available. Reception manages the schedule; see Unread messages.

    If your host manages the icon badge, set Reception.shared.updatesAppBadge = false and implement its combined badge policy. This also disables the SDK's removal of delivered support notifications when the count reaches zero. It does not disable the observable Reception.shared.unreadCount. See Unread messages.

    Push notifications do not arrive

    Verify all three parts of push setup:

    1. The host app has push capability and appropriate signing, registers with APNs through its existing flow, and passes the nonempty token to Reception.shared.setPushToken after configuration.

    2. The app's Apple Push settings contain the matching bundle identifier, Key ID, Team ID, and private key.

    3. A real device has started support and reported a token and environment. Check its push state and any rejection reason in the dashboard.

    The default .automatic environment reads the provisioning profile on a physical device; an unresolved environment prevents the SDK from accepting that token. On the simulator it selects sandbox; An explicit .sandbox or .production override is available when automatic detection is unsuitable, but it must match the token's actual environment.

    A successful simulator chat does not verify APNs delivery. Verify on a real device with notification permission, then test a reply with the app backgrounded. Inspect any reported APNs rejection instead of changing environments at random. See Push notifications.

    On Android, check instead: Firebase Messaging and the google-services.json of the Firebase project whose service-account key is saved under Android (Firebase); exactly one messaging service receiving FCM, either your own that calls Reception.handlePushMessage or the SDK's ReceptionMessagingService with its intent filter; notifications allowed for the app and its “Support replies” channel; and an app that was not force-stopped. Test on a phone or an emulator with Google Play. See Push on Android.

    A push tap does not open chat, or foreground pushes interrupt it

    Forward the notification's userInfo to Reception.shared.handlePushNotification. A recognized payload must contain a reception dictionary with a nonempty string conversationId. The return value means the payload was recognized; it does not prove the conversation was displayed or delivered.

    Use openChat: false for foreground receipt and the default true for a notification tap. A tap presents the SDK sheet, including after a cold start. The host decides whether to show foreground notification banners; Reception.shared.isChatOpen can inform that decision. Keep routing unrecognized notifications through your existing handling. See Push notifications.

    On Android, taps on the SDK's own notifications open the chat without code. If the chat doesn't open in a native app, check that Reception.configure runs in Application.onCreate. In Flutter or React Native, check that Reception.configure runs at startup, from main() or your app's entry file, not only after a later screen such as sign-in; the SDK keeps the tap until then. In Flutter, configure(handlesNotifications: false) makes taps only bring the app forward. If your app shows Reception's notifications itself, pass their data to Reception.handlePushNotification(data). The SDK posts no notification while the chat is visible.

    Identity or metadata is missing or belongs to the previous account

    Configure before calling identify or setMetadata; calls before configuration have no session to update. Supply identity again after login and after Reception.shared.logout(). Identification labels the current device; it does not authenticate your app's user or merge their other devices.

    Metadata values must be strings. setMetadata replaces the pending metadata dictionary, so pass the complete intended set. Updates are synchronized through SDK device-update activity; changing pending identity alone does not register a new device or guarantee an immediate dashboard change. See Identity.

    Call Reception.shared.logout() when switching away from an account, before identifying the next account. Logout clears local support state and starts a fresh device session on later use; it does not delete the previous server records. See Login and logout.

    A customer shows as Unverified

    Unverified appears in the conversation header and customer details when the app sent a name, email, or user ID without an accepted token. Guests without those fields show no badge. For Admins, its tooltip links to the app’s identity verification section with its setup prompt. Check that your app passes a fresh token to identify(token:) (Android: identifyWithToken) after sign-in and on every launch. If Reception rejected the token, your event handler receives identityRejected with the reason. See Identity verification.

    Local colors, fonts, or text are ignored

    Remote appearance is enabled by default. Published remote fields can override corresponding local appearance fields. Check the intended app's published configuration. For an app that should use only local values, set Reception.shared.usesRemoteAppearance = false.

    A custom fontFamily takes precedence over local fontDesign. An explicit dashboard font style overrides it; choose Use app default in the dashboard to keep the app’s custom font. Verify the font is bundled and registered in the host app, and pass the registered font name used with SwiftUI’s Font.custom (Android: a Compose FontFamily built from your font resources). On Android, colors are fixed values: set them again when your app switches between light and dark. Host-supplied text remains host-owned and is not automatically translated. See Appearance for all properties and their defaults.

    Published appearance does not change an open chat

    Saving a draft is different from publishing it. Confirm publication, then keep the configured app active for a refresh and open the chat again. Appearance updates are automatic; reopening does not force a download. A newly fetched snapshot is activated at the next opening so an already visible chat does not restyle midway through a conversation.

    Offline or failed refreshes retain the cached appearance. Also verify that Reception.shared.usesRemoteAppearance is true and that the App ID matches the app you edited and the configuration matches dashboard setup. See Remote appearance.

    Chat, push, or review text uses an unexpected language

    Without an override, the SDK follows the host app's selected localization, not a separate scan of the device's preferred languages. If your app has its own language picker, set Reception.shared.languageOverride at startup and whenever the choice changes. Set it to nil to restore automatic selection.

    On Android, an app without android:localeConfig gets the chat in the phone's language even when the app itself is English-only. Declare the app's languages or set Reception.languageOverride; see Language on Android.

    Unsupported or invalid identifiers fall back to English; supported regional and script variants follow the matching rules in Language. Changing the dashboard preview language edits or previews that translation; it does not change a customer's selected language.

    The server uses the last successfully reported app language for push and review templates. Offline changes can therefore take time to appear there. Existing messages and notifications are not translated retroactively, and custom host text needs host localization.

    Review requests are unavailable or a review is not recorded

    Set the app's numeric App Store ID (Google Play package name for Android) before sending a review card, reopen closed conversations before replying, and remove attachments from a review draft. Repeating a review request shows a warning that asks you to type send review. Reset support does not clear the retained device's review-request history.

    If the recipient's language changed while a review draft was open, review the prompt to retain your text or use the current template before sending. A click receipt or .reviewOpened event records a review-link action, not submission of an App Store review. See Reviews and Events.

    Telegram notifications arrive but replies do not

    Use Telegram's Reply action on a recent support notification in the configured chat. Text and image replies are supported; other media, edits, forwarded messages, bots, and anonymous senders are not. Check that the notification targets the device's latest conversation, and reopen that conversation in the dashboard if it is closed. A reply to a reopened historical thread can be saved without appearing in the customer's current chat.

    Check that the integration is enabled and the bot is dedicated to Reception. Outgoing notification delivery alone does not verify replies. Connecting the same bot to another service can divert replies. If the connection still fails, contact the Reception team with the app and failure time. See Telegram for setup and verification.

    Slack cards arrive but replies do not

    Write your answer inside the card's thread; messages in the channel itself never reach a customer. A saved reply gets Reception's ✅. Without one, look for Reception's note in the thread: it explains, for example, that the conversation is closed, that only images can be attached, or that guests and people from other organizations can't answer customers. Check that Slack is enabled for the app and its settings don't show Needs attention. See Slack for setup and verification.

    History disappears after reset or authentication failure

    An admin reset clears cached chat state, and the next send starts support again. The SDK also clears the local session when the service no longer accepts its session, for example after the device was deleted in the dashboard. Check whether someone reset support or deleted the device or app before assuming the history was lost through connectivity alone.

    Session credentials stay on the device where they were created and do not move with a backup. After someone restores a backup onto a new phone, support starts there with a new, empty chat; the earlier conversation remains in your inbox.

    Logout also starts a new local device session. Reusing the same external user ID does not restore an earlier device's history. See Login and logout and Privacy and data.

    Data deletion fails or old records remain

    When an account is deleted, await Reception.shared.deleteData() instead of calling logout. If deletion fails, the SDK throws ReceptionError and preserves local state so you can retry with the current session. Its public code and status properties help with diagnostics. A status of 0 means no usable HTTP response; inspect code as well. delete_failed means deletion could not complete; some data may already have been removed.

    Do not call logout in a deletion failure handler if you intend to retry. Completion can be local only when there is no stored session, the session has ended, or the App ID is unavailable. It does not prove that earlier server records were erased. After logout, delete the retained device in the dashboard. The API deletes only the current device's support data; it does not find every device sharing the external user ID. See Delete data and Privacy and data.

    Get help

    Something not working? Write to us in the Support chat. We're happy to help. Briefly describe what happens and any error message you see.

    Start with what you tried and what happened instead. For example: “Text messages reach Sent, but a photo stays failed after Retry.” If there is no error message, describe the visible state. You do not need technical logs or error codes to ask for help.

    If you have them, the app name, approximate time, app/iOS versions, and whether you used a simulator or iPhone can help us investigate. Include relevant presentation or language settings only when they relate to the problem.

    Optional developer details

    For a failed deleteData() call, you can include its public ReceptionError.code and status; see SDK errors. These details are optional when asking for help.

    Remove tokens, secrets, private keys, signed image URLs, and customer message content from details you share.