Skip to content
reception

Search documentation

Loading documentation…

    Log in
    Browse documentation

    App integration

    Flutter

    Add Reception's native iOS support chat to a Flutter app with the reception_flutter package. The chat runs entirely in the official Reception iOS SDK, which the package bundles; the Dart API mirrors the React Native and native iOS ones. It needs Flutter 3.44+, Dart 3.12+, iOS 17+ and Xcode 26. Android and web calls complete immediately, log once and return default state.

    View Markdown

    Most teams let a coding agent do the setup: copy the prompt from Settings → your app → SDK setup in the dashboard; it detects Flutter from pubspec.yaml. The rest of this page is what the agent follows and what you need when you change things by hand.

    1. Install

    Terminal
    flutter pub add reception_flutter

    Swift Package Manager and CocoaPods both work without Podfile edits. Set the iOS deployment target to 17.0 or higher at the project level (Xcode: Runner project → Info → iOS Deployment Target, or the three IPHONEOS_DEPLOYMENT_TARGET entries in ios/Runner.xcodeproj/project.pbxproj), and raise any Runner target-level entries below 17.0. If ios/Podfile exists and pins an older platform, set platform :ios, '17.0' there too; a post_install hook that forces an older target on all pods must use 17.0 or skip reception_flutter. The chat follows the languages declared under CFBundleLocalizations in ios/Runner/Info.plist.

    Do not also add the native reception-ios package: the plugin already bundles the SDK, and two copies would share the same storage.

    2. Configure

    Configure once in main(), before showing Support, and after Firebase.initializeApp() and any other notification plugin's setup. Your public App ID is in the dashboard under Settings → your app → General.

    dart
    import 'package:flutter/widgets.dart';
    import 'package:reception_flutter/reception_flutter.dart';
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Reception.configure(appId: 'app_YOUR_APP_ID');
      runApp(const MyApp());
    }

    Reception.isConfigured tells whether the native side accepted the configuration. Pass handlesNotifications: false only if your app routes Reception's own notifications itself; see Push.

    3. Open chat

    Call this from your app's Support button, shown only on iOS (!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS); keep your existing contact path on other platforms:

    dart
    await Reception.openChat();

    Reception.closeChat() dismisses the presented sheet. Reception.isChatOpen is a ValueListenable<bool> of whether the chat is visible.

    Report app events for automations with await Reception.track('paywall_declined', opensChat: true).

    Appearance and language

    Assign a complete ReceptionAppearance; it applies immediately. Colors take a hex string or an adaptive light/dark pair, read from your app's theme so both modes follow the app.

    dart
    Reception.appearance = const ReceptionAppearance(
      accentColor: ReceptionColor.adaptive(light: '#635BFF', dark: '#A59FFF'),
      onAccentColor: '#FFFFFF',
      chatBackground: ReceptionColor.adaptive(light: '#FFFFFF', dark: '#151225'),
      incomingBackground: ReceptionColor.adaptive(light: '#F2F2F7', dark: '#2C2C2E'),
      incomingForeground: ReceptionColor.adaptive(light: '#000000', dark: '#FFFFFF'),
      title: 'Support',
      showsCloseButton: true,
    );

    Other options: welcomeTitle, welcomeText, welcomeIcon (a symbol, an iOS asset image, or none) with welcomeIconColor, welcomeIconSize, welcomeIconCornerRadius and welcomeIconOffset; preferredColorScheme for an app that is always light or dark; closeIcon or closeImage; fontDesign or fontFamily (a font registered with iOS, not a pubspec.yaml font); fadesOlderMessages; and hidesTitle, hidesWelcomeTitle, hidesWelcomeText and hidesPushStatus (the "You'll get a notification when we reply." line). The dashboard's remote appearance overrides these without an app update unless you set Reception.usesRemoteAppearance = false.

    The chat follows the app's language by itself. Only if your app has its own in-app language setting, set Reception.languageOverride = 'de' from it and update it when it changes; null follows the device. Texts are built in for 48 languages; see Text & localization.

    Entry and unread badges

    Reception.unreadCount is a ValueListenable<int>. Show it on the Support entry and on every menu row on the way, and hide the badge at zero:

    dart
    ValueListenableBuilder<int>(
      valueListenable: Reception.unreadCount,
      builder: (context, unread, _) => Badge.count(
        count: unread,
        isLabelVisible: unread > 0,
        child: const Icon(Icons.chat_bubble_outline),
      ),
    )

    The count updates while the app runs and after launch; see Unread messages & badges. Reception.updatesAppBadge = false keeps the app icon badge under your control.

    Accounts and user details

    Identify the person so the team knows who writes:

    dart
    await Reception.identify(ReceptionIdentity.user(userId: user.id, name: user.name, email: user.email));
    await Reception.setMetadata({'plan': 'pro', 'orders': '12'});
    • ReceptionIdentity.user labels the device with a real signed-in account ID and optional name and email; use it with no user ID for a name the person entered without an account.

    • ReceptionIdentity.token carries a signed token from your server for identity verification. The chat emits ReceptionIdentityRejected when the server refuses it.

    • setMetadata replaces the whole dictionary (string values, up to 20 fields); names and emails belong in identify.

    • Call Reception.logout() wherever a signed-in session ends, before the next person's identify, and await Reception.deleteData() on account deletion. Both clear the user details and the push token; send them again with the next sign-in. deleteData throws a ReceptionError with code and HTTP status on failure.

    Push

    Add the Push Notifications capability to the Runner target and your Apple push credentials in the dashboard under Settings → your app → Push Notifications. With the default handlesNotifications: true, the plugin then:

    • registers the APNs device token with Reception,

    • shows Reception banners while the chat is closed and stays quiet while it is open,

    • opens the chat when a Reception notification is tapped, including cold starts,

    • keeps forwarding notifications from Firebase, OneSignal and other services to their own handlers.

    It never requests permission: after your own permission request, call await Reception.registerForPushIfAuthorized(). If you prefer, turn on Ask for push notifications in the dashboard: the chat then asks with a small card right after the person's first message, with no code in your app; see Push notifications.

    Apps that get the APNs token elsewhere, for example from Firebase's getAPNSToken(), pass it on with Reception.setPushToken(hexToken); FCM tokens are rejected. Apps that route notifications themselves (handlesNotifications: false) call await Reception.handlePushNotification(payload, openChat: tapped) for every notification; it returns true for Reception's. Payload shape, APNs setup and verification are on the push notifications page.

    Paywalls

    Register the paywalls your app can show, so the team, automations and the AI can send offer cards that open them:

    dart
    Reception.paywalls = [ReceptionPaywall(id: 'plans', title: 'Plans')];
    Reception.onPaywall = (id) => showPaywall(id); // the chat stays open behind it
    Reception.paywallAvailability = (id) async => !await isSubscribed(); // optional

    Reception.availablePaywalls lists the registered paywalls that are available right now. Call Reception.refreshPaywalls(invalidate: true) after a purchase or subscription change. Pending offers become unavailable on failures, timeouts and hot restarts. The paywalls page has drop-in files for RevenueCat, Superwall and Adapty that fill paywalls and report the person's plan as user details.

    Screens for link cards

    Link cards open websites, other apps, the App Store, Mail and the phone without code. To let them open screens of your app too, list the screens once at startup; the dashboard then offers them by name and sends a screen link only to app versions that have it:

    dart
    Reception.screens = [
      ReceptionScreen('settings', onOpen: () => router.push('/settings')),
      ReceptionScreen('paywall', onOpen: showPaywall),
      ReceptionScreen.withValue('order', value: 'Order number', onOpenWithValue: (number) => router.push('/orders/$number')),
    ];

    onOpen runs after the chat closes. IDs use letters, digits, _, - or ., at most 64 characters, and stay stable: a renamed ID is a new screen. Set the list again at startup after a hot restart; until then the app reports no screens. The dashboard's Add a link → Screen in your app has a prompt for a coding agent that finds your screens and writes this list.

    Embedded chat

    ReceptionChatView() embeds the chat in your own screen instead of the sheet; give it a defined size, and your screen owns dismissal. The welcome texts, appearance and unread count apply the same way. Reception.closeChat() does not close an embedded view.

    Events and diagnostics

    Reception.onEvent receives ReceptionChatOpened, ReceptionMessageSent, ReceptionImageSent, ReceptionReviewOpened, ReceptionPaywallOpened, ReceptionLinkOpened, ReceptionDataDeleted and ReceptionIdentityRejected(error). Assignment replaces the previous handler; a hot restart clears it, so assign it in main(). See Events & callbacks.

    Reception.logLevel = ReceptionLogLevel.debug prints the SDK's log lines (subsystem com.reception.sdk in Console) while you set things up. Reception.version is the bundled iOS SDK version.

    Build and simulator checks

    Build and run on an iOS simulator with flutter run, or build once with flutter build ios --simulator --debug and install build/ios/iphonesimulator/Runner.app with xcrun simctl install. Debug simulator builds support the SDK's launch arguments: -ReceptionSetupCheck <app id> sends the first message and logs the result, and -ReceptionPreview welcome or conversation opens the chat with example data; the setup page explains them. Let main() finish configuring Reception before reading the result.

    For package:reception_flutter/testing.dart, configureReceptionForTesting(appId:, serviceUrl:) points a Debug simulator build at a local Reception backend; it is a no-op in release builds.

    Updating

    Run flutter pub upgrade reception_flutter, then pod install in ios/ if the project has a Podfile, and rebuild. The changelog lists what each release changes; the dashboard shows an update card when a newer version is available.